23

荐 【C++100问】深入理解理解顶层const和底层const

 4 years ago
source link: https://blog.csdn.net/TeFuirnever/article/details/103011514
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

欢迎关注WX公众号:【程序员管小亮】

专栏C++学习笔记

1)该文章整理自网上的大牛和相关专家无私奉献的资料,具体引用的资料请看参考文献。

2)本文仅供学术交流,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。

3)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢谢。

4)此属于第一版本,若有错误,还需继续修正与增删。还望大家多多指点。大家都共享一点点,一起为祖国科研的推进添砖加瓦。

文章目录

  • 欢迎关注WX公众号:【程序员管小亮】

最近在恢复写博客,较真之前写过的博客—— 《C++ Primer》学习笔记(二):变量和基本类型 ,看到了关于【顶层const和底层const】,但是一直不解其意,就简单总结一下在网上看到的相关资料,方便理解,相关说明可以看上面的声明。

个人C++专栏(最近会一直更新的):

一、顶层const和底层const对比

《C++primer》中写到:

const
const

指针类型既可以是顶层 const 也可以是底层 const

int i = 0;
int *const p1 = &i;       // 不能改变p1的值,这是一个顶层const
const int ci = 42;        // 不能改变ci的值,这是一个顶层const
const int *p2 = &ci;      // 允许改变p2的值,这是一个底层const
const int *const p3 = p2; // 靠右的const是顶层const,靠左的const是底层const
const int &r = ci;        // 用于声明引用的const都是底层const

即(除了 const int ci = 42; //顶层const ):

  • 如果 const 右结合修饰的为 类型 或者 * ,那这个 const 就是一个底层 const
  • 如果 const 右结合修饰的为 标识符 ,那这个 const 就是一个顶层 const

非官方定义,用来记忆为主。

不过个人感觉更好的理解还是 stackoverflow——What are top-level const qualifiers? 上的,总结来说:

  • 被修饰的变量本身无法改变的 const 是顶层 const
  • 通过指针或引用等间接途径来限制目标内容不可变的 const 是底层 const

给了两个例子:

// 底层const
char x;
char const* p = &x;

// 顶层const
char x = 't';
char *const p = &x;

当然还有轮子大神的解释 知乎——顶层const与底层const。C++的对象中的对象究竟是指?

ZBvYfq2.png!web 我的理解是 const 的位置很重要,即 const intint const 的区别非常重要,不过我还不能完全理解这其中的区别,可能学完能有一个新的认识吧。。。fighting!

小结一下:主要的理解问题基本可以得到解决,认识哪一个是什么即可,这一点上 stackoverflow 显然更清晰,除此之外,最大的问题应该是中文对于底层 const 的翻译,英文原文的两个单词是:

top-level const
low-level const

对的,你没看错,是 low 而不是 bottom 。。。所以或许成为低层更恰当???

二、顶层const和底层const区别

当执行拷贝操作时,常量是顶层 const 还是底层 const 的区别就非常明显了:

  • 顶层 const 没有影响。拷贝操作不会改变被拷贝对象的值,因此拷入和拷出的对象是否是常量无关紧要。
i = ci;     			// ok: 拷贝ci的值,ci是一个顶层const,对此操作无影响
p2 = p3;    			// ok: p2和p3指向的对象类型相同,p3顶层const的部分不影响
  • 底层 const 的限制不能忽视。拷入和拷出的对象必须具有相同的底层 const 资格,或者两个对象的数据类型可以相互转换(一般来说,非常量可以转换成常量,反之则不行)。
int *p = p3;    		// error: p3包含底层const的定义,而p没有
p2 = p3;        		// ok: p2和p3都是底层const
p2 = &i;        		// ok: int*能转换成const int*
int &r = ci;    		// error: 普通的int&不能绑定到int常量上
const int &r2 = i;  	// ok: const int&可以绑定到一个普通int上

三、剥洋葱

最后举一个例子,证明【剥洋葱】,从右向左看更容易理解:

const int *p // p是指针,指向int,int是const, 「*p」类型为int并且不可变;是低层const;
int *const p // p是const,是常量指针,指向int, p属于「int *」并且不可变;是顶层const;

参考文章


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK