如果我正确解释 C++ 引用,它们就像指针,但具有保证的数据完整性(没有 NULL,没有 (int*) 0x12345)。但是当引用对象的范围被保留时会发生什么?如果没有涉及魔法(可能不是),引用的对象将在我背后被销毁。
我写了一段代码来检查这一点:
#include <iostream>
using namespace std;
class A {
public:
A(int k) { _k = k; };
int get() { return _k; };
int _k;
};
class B {
public:
B(A& a) : _a(a) {}
void b() { cout << _a.get(); }
A& _a;
};
B* f() {
A a(10);
return new B(a);
}
int main() {
f()->b();
}
The _k
放入实例变量以检查堆栈帧是否存在。
令人惊讶的是,它没有出现段错误,而是正确打印“10”,而我认为A
分配在堆栈上并且该堆栈帧f()
至少会被覆盖cout<<
call.
这是未定义的行为,你很幸运,记忆a
尚未用于其他任何用途。在更复杂的情况下,你几乎肯定会得到垃圾。在我的机器上,我用这段代码得到随机垃圾。对我来说,这可能是因为我使用的是 64 位机器,它使用寄存器调用约定。寄存器比主内存更频繁地被重用(理想情况下......)。
所以回答你的“发生了什么”的问题。在这种情况下,引用可能只不过是具有更友好语法的有限指针:-)。在引擎盖下的地址a
被储存了。后来的a
对象超出范围,但是B
对象对此的引用a
不会“自动神奇地”更新以反映这一点。因此你现在有一个无效的参考。
使用这个无效的引用几乎会产生任何结果,有时会崩溃,有时只是垃圾数据。
EDIT:感谢 Omnifarious,我一直在思考这个问题。 C++ 中有一条规则,基本上是说如果你有一个临时变量的 const 引用,那么临时变量的生命周期至少与 const 引用一样长。这引入了一个新问题。
EDIT:对于那些感兴趣的人来说,转移到单独的问题(对临时异常的 const 引用 https://stackoverflow.com/questions/3097806/const-reference-to-temporary-oddity)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)