C++那些细节--顶层const和底层const

C++中const的理解 详细介绍C++语言的const关键字的各种用法。 阅读详情

看到这个顶层const和底层const,纠结了好久,经常记不住。

于是本人的强迫症发作,一定要记住,就写下了这个笔记...

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;



int _tmain(int argc, _TCHAR* argv[])
{
	int b = 0;
	int c = 1;
	const int* pa = &b;//这里是底层const,不能改变*pa的值;
	//*pa = 2; 错误
	pa = &c;//改变pa本身

	int* const pb = &b;//这里是顶层const,不能改变pb本身的值;
	//pb = &c; 错误
	*pb = 2;//改变pb所指对象的值
	
	return 0;
}
《C++Primer》中对于顶层const和底层const是这样描述的:

我们知道,指针本身是一个对象,因为,指针实际对应着内存单元的一段存储空间,然而,指针所指向的也是一个数据对象,因此,指针是一个常量与指针所指向的是一个常量是两个完全不同的概念, 顶层 const 表示的是 指针本身是一个常量 , 底层 const 表示的是 指针所指的对象是一个常量 ,更一般情况下, 顶层 const 可以表示任意对象是一个常量 ,这对于算术类型、类、指针等任何数据类型都是成立的, 底层 const 则与指针和引用等复合类型的基本类型部分有关,比较特殊的是,指针既可以是顶层 const 也可以是底层 const ,这一点与其他类型区别明显。

2. 顶层 const 与底层 const 在执行拷贝操作时的不同


对于顶层 const 与底层 const ,在执行对象拷贝时有着明显的不同:


(1)顶层 const 不受什么影响


int i = 0;
const int ci = 42;   // 不能改变 ci 的值,这是一个顶层 const
i = ci;   // 正确:ci 是一个顶层 const,对此操作无影响
const int *p2 = &ci;  // 允许改变 p2 的值,这是一个底层 const
const int *const p3 = p2;  // 靠右的 const 是顶层 const ,靠左的是底层 const
p2 = p3;   // 正确:p2 和 p3 指向的对象的类型相同,p3 顶层 const 的部分不影响
(2)底层 const 的限制不能忽略, 要求拷出和拷入的对象有相同的底层 const 资格或者能转换为相同的数据类型,一般非常量能够向常量转换,反之则不行


int *p = p3;  // 错误:p3 包括底层 const 定义,而 p 没有
p2 = p3;   // 正确:p2 和 p3 都是底层 const
p2 = &i;   // 正确:int* 能转换成 const int*
int &r = ci;  // 错误:普通的 int& 不能绑定到 int 常量上
const int &r2 = i;  // 正确:const int& 可以绑定到一个普通 int 上
来分析一下以上的代码:


int *p = p3; 
p3 既是一个顶层 const 又是一个底层 const,在执行对象拷贝时,顶层 const 部分没有任何影响,完全不用考虑,但是 p3 又是一个底层 const ,它要求拷入的对象有相同的底层 const 资格,而 p 没有,所以是错的;


p2 = p3; 
p3 要求拷入的对象拥有相同的底层 const 资格,p2 也是一个底层 const,故正确;


p2 = &i; 
对 i 取地址将得到 int* , p2 是 const int* ,前者是非常量,后者是常量,赋值语句等号右侧的类型向左侧转换,非常量能够向常量转换,故正确;


int &r = ci; 
由左侧部分我们知道,需要得到的是一个绑定到 ci 上的引用,而绑定到 ci 上的引用的类型是 const int& ,等号左侧的类型是 int& ,赋值语句等号右侧的类型向左侧转换,但是常量不能向非常量转换,所以是错误的;


const int &r2 = i; 
由左侧部分我们知道,需要得到的是一个绑定到 i 上的引用,而绑定到 i 上的引用的类型是 int& ,等号左侧的类型是 const int& ,赋值语句等号右侧的类型向左侧转换,一般非常量可以向非常量转换,所以是正确的。

C++函数重载与声明深度解析:从底层const到作用域隐藏 函数重载是C++多态性的基础实现方式,它允许在同一作用域内定义多个同名函数,编译器通过形参列表的差异来区分它们。其核心原理在于编译时的名称修饰和类型匹配机制,通过生成不同的内部符号来实现函数的多版本共存。这一技术价值在于提升了代码的表达力和可读性,允许开发者使用统一接口处理不同类型的数据。在实际应用场景中,函数重载广泛用于数学运算库、容器类接口设计和工厂模式等。理解顶层const与底层const的区别至关重要,前者修饰对象本身,通常不影响重载;后者修饰指针或引用所指对象,是构成有效重载的关键。同时,作用域规 阅读详情

相关推荐

C++11 为什么auto类型说明符会忽略顶层const

假如某个函数返回类型 const T,形如: const T SomeFunction(); 你很可能希望有一个可变的变量接收这个值: auto t = SomeFunction(); t.Modify(); 反过来,你也有时会希望把一个可变的值变成const引用 vector<T> container; for (const auto& t : container)…所以最顶层那个const经常会根据需要变化。如果没有这个feature会不那么方便。 ...

二进制君 1万+

笔记2:C++函数形参会忽略顶层const而保留底层const

形参中的顶层const分为两种情况 1)形参为非指针类型 此时,TestA与TestB的函数是等价的,TestB会忽略形参中的const属性,因为形参只是临时量,只是实参的副本,函数调用结束后就会被销毁,因此形参是否是常量不会影响主调函数及实参,但若是形参是指针或者引用时就会对实参产生影响。2)形参为指针类型 2)形参为指针类型 TestA时,形参为顶层const指不能修改tmp指针的指向,但调用函数会传入一个实参,即指定了tmp的指向,此时的const没有实际意...

m0_50041703的博客 863

一文搞懂雷达脉冲压缩和匹配滤波器

为了解决传统单频脉冲雷达面临的作用距离和空间分辨力之间的矛盾,脉冲压缩理论被提出。在接收端设计一个和发射信号能够“共轭匹配”的网络来实现脉冲压缩。接收到的回波信号通过匹配滤波器时,滤波器的增益在信号越强的频率点越大;在信号越弱的频率点,增益越小,通过这样的方式使信号在时域更加集中。脉冲压缩技术大致可分为线性调频(LFM)和相位编码。其中LFM信号易于通过硬件或各种技术产生,但是进行匹配滤波后主旁瓣比高达13.2dB,在检测多个目标时,强目标的回波旁瓣可能会把弱小信号覆盖,导致弱小信号的检测受到影响。

FPGA入门到跑路 9935

C++的顶层const和底层const的理解

最近,又一次翻开C++primer,决定仔细研究一下自己以前没搞懂的顶层const和底层const,这次看了后感觉明白了,所以记录下来,以后可以没事翻阅,增加记忆。首先,const是一个限定符,被它修饰的变量的值不能改变。对于一般的变量来说,其实没有顶层const和底层const的区别,而只有向指针这类复合类型的基本变量,才有这样的区别。 一 如何区分顶层const和底层const指针如果添加co...

冬之晓 3万+

XMind文件解析黑科技:用Python实现版本自适应读取(兼容2010-2024)

本文深入探讨了如何利用Python实现XMind文件的版本自适应解析,兼容从2010到2024年的各版本。通过分析XMind文件作为ZIP压缩包的本质,文章提供了智能探测文件内部结构(JSON或XML)并构建健壮读取逻辑的完整方案,有效解决了版本兼容性难题,并演示了将解析数据转换为PlantUML等下游应用的实战案例。

weixin_29041767的博客 682

MATLAB射线追踪算法实战:从零搭建通信信号传播模型(附完整代码)

本文提供了一份详细的MATLAB射线追踪算法实战指南,指导读者从零开始搭建通信信号传播模型。内容涵盖场景建模、射线发射、路径追踪与信号计算等核心环节,并附有完整代码,帮助通信与电子工程领域的学习者和工程师快速掌握这一精确模拟电磁波传播的关键技术。

weixin_29092031的博客 196

C++ 限定符Const要点

基本概念 一旦一个变量用const去修饰,那么这个变量的值在接下来的程序运行过程中就不能改变。如: const int buffersize = 512;//const 整形常量初始化 buffersize = 256;//错误,因为buffersize已经定义为整型常量无法修改 以下是相关const用法一些小细节。 const常量初始化 int i = 42; const int ci...

weixin_37661692的博客 181

将Dify平台开发的工作流集成到Open WebUI中

将Dify开发的工作流集成到Open WebUI是一个能够显著增强AI应用交互能力和业务逻辑深度的有效途径。其核心在于通过API建立两者间的通信桥梁,并确保API在格式、协议和行为上的一致性,特别是向OpenAI Chat API规范看齐。最简单直接的路径是利用Dify的“对话型”或“Agent型”应用,这类应用的API设计更倾向于满足Open WebUI这类聊天前端的期望。然而,面对复杂的现实场景,直接的完美兼容并非总是唾手可得。

形上得其象,形下合于数;阴阳自济,玄理自明。 2030

C++基础:const关键字

在编程的时候,我们有时候希望定义这么一个对象:其内容在初始化后不能再修改。这个时候const关键字就排上用场了。 当一个对象被const修饰后,这个对象的内容在初始化后,再也无法被修改。值得注意的是,const修饰的对象必须要初始化。 可以看看以下面的例子: int a = 10; //a是常量 //const int i; //编译器报错,因为const修饰的对...

培培哥的专栏 425

使用GitLab的VS Code插件 GitLab Workflow 来进行项目的DevOps管理,助力研发效能

使用VS Code的GitLab Workflow插件,进行项目的DevOps管理,将效率提升到MAX。直接在VScode中管理流水线,一键跳转到创建 Issues,MR

知无涯 5291

《深入掌握MongoDB数据库》 - 专栏介绍和目录

本专栏系统讲解MongoDB从基础到高级的全栈知识,涵盖安装配置、核心操作、性能优化、安全运维等核心内容。基础部分包括CRUD操作、数据类型、查询语法等入门知识;进阶部分深入索引优化、聚合查询、事务处理等高级特性;核心原理解析存储引擎与数据格式;安全运维则聚焦访问控制、认证机制、审计日志等企业级实践。通过实战案例与最佳实践,帮助开发者全面掌握MongoDB在不同场景下的应用,适合各层次技术人员系统学习。

数据知道的博客 2993

【C++】编程、基础知识

1C++(编程、基础知识)

uytguytgf的博客 614

Python 爬虫实战:从零搭建第一个爬虫程序(附完整代码)

本文介绍了Python网络爬虫的入门实战,以豆瓣Top250电影榜单为例,详细讲解爬虫开发全流程。内容包括爬虫基础原理、环境搭建、请求发送与响应处理、数据解析与保存等核心环节,并提供了可直接运行的完整代码示例。文章还分析了常见问题解决方案,并强调了爬虫开发的合规注意事项。通过本教程,读者可快速掌握Python爬虫的基本思路和实操技巧,为后续深入学习BeautifulSoup、XPath等进阶技术打下基础。

2503_91057718的博客 2316

<<Effective C++>>读书笔记(一)

条款03 尽可能使用const 分清顶层const和底层const的区别 顶层const指的是const在*号的右边,表示指针本身是一个常量,无法修改对象本身. 底层const指的是const在*号的左边,表示的则是指针所指的对象是一个常量, 无法修改其指向的对象 对于内置数据类型来说const无所谓底层(基本类型没有指向某个对象的意思)的概念,引用本身不是对象 所以也无所谓顶层const,只有指针

zyfforlinux 729

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C++新标准,查漏补缺(1)基础

本文是读《C++ Primer》(第五版)的笔记,但并不是事无巨细的笔记,而是一个C++98的老鸟,学习C++11,依据以往经验实践,对新标准的一种体会。 本文不面向新手,一方面给自己看,一方面希望有同样背景的C++开发人员能有所得,包含大量案例,如有不足,欢迎指正,共同学习。

Otosu的专栏 1399

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

彻底搞懂 C++ 中 顶层 const 和 底层 const

彻底搞懂 C++ 中的 顶层 const 和 底层 const,分析了 指针常量 和 常量指针与之的关系,分析了 引用 中 const 的使用,总结了 顶层 const 和底层 const 对含有 const 类型转换的公式,理解其实际意义

h2763246823的博客 3194

C++对于底层和顶层const的理解

    const对于不涉及指针的常量来说,没什么区别,限定一个常量不会被修改。     在涉及指针的时候,和const位置的不同表达的含义就有所不同,其含义也就有所差别,看如下程序: #include<bits/stdc++.h> using namespace std; int main() { in...

挪威的森林 195

C++ const重载:顶层与底层const如何决定函数签名?

C++中的const限定符常被认为与函数重载存在微妙关系:某些场景下const参数导致重定义,另一些场景却能构成合法重载。其背后分水岭在于顶层const与底层const的区别——修饰参数副本本身的顶层const不改变调用接口,而修饰指针指向对象或引用绑定对象的底层const则代表调用方可操作能力的不同。按值传参时const被抹平,指针与引用场景可分流重载,成员函数中this指针层面的const更开辟了只读/可写双版本的设计范式。这一机制不仅支撑STL容器的const重载接口,也为日常类设计提供“读路径优先c

weixin_33491377的博客 329

C++ 中 char\ 、const char\ 、char\ const、const char\ const 的区别:一篇彻底讲清指针与 const 的组合

fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;是否是否是否声明: X ptrconst 在 * 左侧?指向的内容不可修改指向的内容可以修改const 在 * 右侧?const 在 * 右侧?指针和内容都不可修改指向的内容不可修改指针可修改内容可修改指针不可修改char*内容和指针都可修改这四种声明的本质区别在于。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 1225

1.C和C++区别,以及const分析(底层const/顶层const)

从本章起开始从0学习C++,本章主要内容: 1)C和C++的基本区别 2)C和C++的const区别 1.C++和C区别 1.1 C++更强调语言的实用性,所有变量都可以在需要时再定义 比如: for(int i=0;i<100;i++); 1.2 C++不允许定义多个同名全局变量,而C却可以重复定义 1.3 C++的register只是个兼容作用 1.4 C++的所有标识符都必...

抵抗时间扭曲,坚持做一件有意义的事 274

C++ const 深度解析:从常量定义到编译器优化,彻底理解 const 的全部用法

fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;const在左侧const在右侧const同时在两侧遇到 const 和指针声明从右往左读类型const 出现在哪?底层 const指向的内容不可修改指针本身可以指向别处顶层 const指针本身不可修改指向的内容可以修改两层 const指针本身不可修改。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 1386

[C++]const 限定符和 constexpr 关键字

对const和constexpr关键字的介绍

A_ns_wer_的博客 1510

深入理解C++的Const关键字:从语法到语义的全面剖析

多用const:它是最好的文档之一,可以防止意外修改,让编译器帮你发现错误。理解底层/顶层const:特别是在函数参数和返回值中。追求逻辑常量性:设计const成员函数时,思考的是“对象的表现行为是否改变”,而不仅仅是“位是否改变”。慎用mutable:将其仅限于缓存、调试计数、互斥锁等内部簿记用途。利用重载:使用“非const调用const”的技巧来避免代码重复。const与线程安全:从逻辑上讲,const成员函数应该是线程安全的。因为多个线程同时调用一个对象的const方法应该是安全的。

码事漫谈 1299
上一篇: C++文件操作(windows平台下的)
下一篇: 《C++Primer》读书笔记(6)
puppet_master
puppet_master 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄12年 2695粉丝 161原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值