C++变量与引用赋值区别及函数返回引用问题
两者本质完全不同,观测到表现相似只是测试场景没有触发二者的行为差异
首先明确func()本身的行为:函数返回的是绑定到全局变量a的左值引用,调用func()本身不会产生任何值拷贝,拿到的就是a本身的别名。
两个变量的初始化逻辑从底层来说完全是两套逻辑:
int &b = func();是引用绑定:b直接成为a的别名,和a指向同一块内存地址,整个过程没有任何数据拷贝,对b做读写操作本质就是直接操作a的内存。int c = func();是值拷贝初始化:初始化时会读取func()返回的引用指向的a的当前值,把这个值复制到c专属的独立内存空间中。初始化完成后,c和a、b就没有任何关联了。
你觉得二者表现没有差异,大概率是只在初始化完成后立刻读取了两个变量的值——此时c刚从a拷贝了初始值,和a、b存储的数值当然完全一致,看起来没有区别。只要加几行修改值的测试代码,差异会立刻显现:
#include <iostream> int a = 10; int& func() { return a; } int main() { int &b = func(); int c = func(); // 初始状态三者值均为10,这就是你之前观测到的"无差异"场景 std::cout << "初始值: a=" << a << ", b=" << b << ", c=" << c << "\n"; // 修改全局变量a的值 a = 20; std::cout << "修改a后: a=" << a << ", b=" << b << ", c=" << c << "\n"; // 修改变量c的值 c = 30; std::cout << "修改c后: a=" << a << ", b=" << b << ", c=" << c << "\n"; return 0; }
运行输出结果如下:
初始值: a=10, b=10, c=10 修改a后: a=20, b=20, c=10 修改c后: a=20, b=20, c=30
从结果可以直接看到差异:b作为a的引用,值会随a的修改同步变化,修改b也等价于修改a;但c是独立的副本,a的修改不会影响c,修改c也不会反向影响a。
另外补充你提到的「返回局部变量引用」的相关注意点:你当前贴的代码是合法的,因为返回引用绑定的是全局变量a,生命周期覆盖整个程序运行周期,不存在悬垂问题。如果func()内部定义了局部栈变量,再返回这个局部变量的引用,那么函数返回时局部变量就已经被销毁,此时不管是用引用接收返回值,还是用普通变量拷贝接收,都会触发未定义行为——前者直接拿到悬垂引用,后者读取已经销毁的对象的值本身就是非法操作。
内容的提问来源于stack exchange,提问作者user3557062
相关产品推荐
相关产品推荐

