为何C++引用赋值的两段代码表现不同?如何正确理解引用绑定特性
C++引用赋值的认知误区与核心特性解析
核心本质澄清
《C++程序设计语言》中提到的“引用在完成初始化后,无法再指向其他对象”的描述是完全准确的。
日常使用中最容易产生的认知偏差,是把对引用的赋值操作,误判为引用重新绑定目标——实际上,因为引用是其绑定对象的别名,所有作用在引用上的操作,本质都是直接操作它最初绑定的那个原始对象,引用本身没有独立的内存实体,根本无法被“重新指向”。
两段代码的运行差异拆解
第一段代码输出20的逻辑
逐行执行流程:
- 定义变量
a并赋值10,定义变量b并赋值20 - 执行
int& ref = a,此时ref正式绑定为a的别名,和a共享同一块内存 - 执行
ref = b:这行代码的语义完全不是让ref改绑到b,而是把b当前存储的整数值,写入ref绑定的内存空间,也就是直接修改a的值。执行完这行后,a的值已经从原来的10变成了b的20 - 最后输出
ref,本质是输出a的值,因此得到20——这就是看起来像ref改指b的错觉来源。
第二段代码输出10的逻辑
逐行执行流程:
- 定义未初始化的变量
a、b,此时两个变量存储未定义的随机值(这段代码因为对未初始化的b直接取值赋值,本身存在未定义行为,但这个行为不影响我们对引用绑定逻辑的判断) - 执行
int& ref = a,ref绑定为a的别名,绑定关系从始至终不会改变 - 执行
ref = b:同样是把当时b的随机值写入a的内存空间,让a、b值相等,但ref的绑定对象仍然是a,这步操作本质是值拷贝,完全不涉及绑定关系的修改 - 后续依次执行
a = 10(直接修改绑定的a对象)、b =20(修改和ref无关的b对象) - 最后输出
ref,本质是输出当前a的值10——这个结果刚好戳破了“ref改绑b”的错觉,证明引用的绑定关系从来没有变动过。
常见认知对比
可以和指针的语义做个直观区分:
- 可重新赋值的指针:
int* p = &a; p = &b是真的修改指针本身的存储地址,让指针从指向a改成指向b,后续对*p的操作会作用在b上 - 引用:所有给引用名的赋值操作,都只是通过别名修改绑定对象的值,永远不会改变绑定关系本身。
内容的提问来源于stack exchange,提问作者Chenglong Li
相关产品推荐
相关产品推荐

