专栏C++学习笔记

声明

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

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

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

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



文章目录


    〇、前言

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

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

    • 《C++ Primer》学习笔记/习题答案 总目录
    • 《C++ Primer》学习笔记(二):变量和基本类型
    • 《C++ Primer》习题参考答案:第2章 - 变量和基本类型

    一、顶层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++的对象中的对象究竟是指?​​:

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

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


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

    • ​top-level const​​ 顶层 const
    • ​low-level const​​ 底层 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;


    如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~

    回复【福利】即可获取我为你准备的大礼,包括C++,编程四大件,NLP,深度学习等等的资料。

    想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~

    【C++100问】深入理解理解顶层const和底层const_参考文献_02