为什么C++允许传递未初始化元素的引用?对应示例代码可编译的原因是什么?
问题核心本质
你写的这段代码能编译通过,不代表它是合法可正常运行的C代码,它属于标准明确规定的未定义行为,只是C的编译检查规则没有禁止这种写法而已,核心原因有三个:
- 编译器的语法检查只做表层校验
C++标准要求类的引用类型成员必须在构造函数的初始化列表中完成绑定,编译器只会检查你有没有遵守这个语法规则:你在初始化列表里给a赋值了,赋值的右值this->a是一个合法的左值表达式,语法层面完全符合要求,自然不会报编译错误。 - 初始化列表执行阶段
this指向的内存已经分配完成
在进入构造函数初始化列表时,Demo对象的内存已经在栈/堆上分配好了,所有成员的地址都是确定的,this->a可以拿到合法的内存地址,编译器只需要把引用a绑定到这个地址上就可以完成初始化流程,不会额外检查这个地址上的引用本身是不是已经完成了绑定。 - 引用绑定不需要调用目标类型的构造函数
你把int替换为任意类型的引用都不会触发构造函数调用,引用本质上只是一个自动解引用的指针,绑定操作只需要取目标地址,和目标类型的构造函数是不是公有完全无关,所以就算你用私有默认构造的类的引用,编译也能通过。
额外提醒
这段代码虽然能编译,但完全没有实用价值:你相当于让引用a绑定到了它自己所在的内存地址,后续任何对a的访问都是未定义行为,可能直接崩溃,也可能读到随机垃圾值,运行结果完全不可控。
C++的设计哲学是信任程序员的判断,不会做过多的强制安全检查,以此换取极致的性能和灵活性,这种写法被允许,只是语言把「要不要写合法代码」的选择权交给了你而已,不代表这种写法是正确的。
内容的提问来源于stack exchange,提问作者lesserfish
相关产品推荐
相关产品推荐

