惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
S
SegmentFault 最新的问题
Jina AI
Jina AI
D
DataBreaches.Net
人人都是产品经理
人人都是产品经理
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
大猫的无限游戏
大猫的无限游戏
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
B
Blog
博客园 - 【当耐特】
博客园 - Franky
M
MIT News - Artificial intelligence
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LangChain Blog
MyScale Blog
MyScale Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 叶小钗
Last Week in AI
Last Week in AI
Engineering at Meta
Engineering at Meta

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派
代码#1 - 区分常量引用、常量指针和指向常量的指针 - 少数派
2019-09-18 · via 少数派

因为没有系统的学过 C++,最近在开发过程中反反复复被引用和指针摩擦,索性系统地跟着 「C++ Primer」一书好好整理了下相关知识。


预备知识

引用

  • 引用属于复合类型,为所引用的对象取了别名;
  • 引用本身不是对象,引用指向某个对象;
  • 一旦初始化完成,引用将和它的初始值对象一直绑定在一起;

指针

  • 指针属于复合类型,存放某个对象的内存地址;
  • 指针本身就是一个对象(在内存中有自己的存储地址),作用是指向另一个对象,以方便调用所指向的对象;
  • 如果修改了指针本身(即所存储的内存地址),自然就改变了它所指向的对象;

引用与指针的结合使用

  • 引用本身不是对象,所以不能定义「指向引用的引用」或「指向引用的指针」;
  • 指针本身是一个对象,所以可以定义「指向指针的指针」和「指向指针的引用」;

const 限定符

  • const 对象一旦创建后,其值就不能再改变;
  • 如果 const 关键词用于基本类型的变量,其用意就是变量的值不会被改变;
  • 如果 const 关键词和复合类型变量(例如指针或引用)一起使用,「复合类型变量本身是不是常量」和「其所指向的值是不是变量」,就是两个独立的问题。

常量引用 (reference to const)

  • 常量引用为约定的叫法,完整含义是一个「指向 const 对象的引用」;
const int ci = 1024;
const int &r1 = ci; //引用的类型必须和与之绑定的对象严格匹配
  • 根据 const 的定义,r1 所指向的值(即 ci)不能通过 r1 改变(反过来想,如果可以通过 r1 改变 ci 的值, const 关键词的使用毫无意义);
  • 常量引用所指向的对象,不一定是常量,可以通过其他途径改变其值。例如:
int i = 42;
int &r1 = i;
const int &r2 = i;
r2 = 0; //不合法,不能通过 r2 去改变 i 的值;
r1 = 0; //合法,r1 是普通引用

指向常量的指针(pointer to const)

  • 与常量引用类似,pointer to const 所指向的对象,不一定是常量,可以通过非 const 对像去改变其值;
double pi = 3.14;
const double *r1 = π
double *r2 = π
*r1 = 0; // 不合法,不能通过 r1 修改 pi 的值;
*r2 = 0; // 合法,r2 是普通指针;
  • 与引用不同,指针本身就是一个对象,所以 pointer to const 本身的值是可以被改变的(当然改变后就指向了其他对象);

const pointer

  • 译为常量指针,但是与常量引用不同,它的定义是「指针本身为常量」,不变的是指针本身(即其所表示的内存地址)而非指向的那个值。
  • const pointer 只能保证指针本身是常量,但不能说明其指向的对象是否为常量:
int errNumb = 0;
int *const curErr = &errNumb;  // curErr 是 const pointer, 但指向了普遍变量 errNumb,curErr 可以去修改 errNumb 的值;
const double pi = 3.14159; 
const double *const pip = π // pip 指向了一个 const 对象,所以不能通过 pip 去改变 pi 的值;

注意:常量指针中,const 起到类型符的作用,声明了一个常量。而在常量引用中,const 是类型修饰符,去修饰引用符。

小结

当 const 关键词与指针和引用结合使用时:

  1. 使用 pointer to const 与 reference to const 时,编译器自认为它们指向的是 const 对象,所以不能通过它们去修改其所指向的对象的值。但其实允许它们指向一个非 const 对象,也就允许通过其他途径修改所指向对象的值;
  2. Pointer to const 的特殊之处在于,它本身的值是可以改变的。所以它既不能保证自己的值不被改变,也不保证其所指向的值不能改变,只能保证不通过这个指向常量的指针去改变所指向的对象的值
  3. Const pointer 只能保证自己的值(内存地址)不能改变。与 pointer to const 或 reference to const 不同的是,允许通过这个指针去改变所指向的值(如果所指向的是不是常量的话)。

参考