我正在使用C ++和const引用,并且很困惑为什么这段代码有效:
#include <iostream>
class A {
public:
A() : a_(50) {}
const int& getA() const { return a_; }
private:
const int a_;
};
int main(int argc, char* argv[])
{
A* a = new A();
const int& var = a->getA();
std::cout << var << std::endl;
delete a;
std::cout << var << std::endl;
}
结果:
50
50
以下是我的想法:
var存储对a_的引用 删除a时,也应删除a_ 当再次访问var时,它不再包含有效的引用,并且应该发生分段错误。
为什么这样做?我不相信我是临时副本。
答案 0 :(得分:13)
您删除a
的那一刻,访问var
成为您进入未定义行为的大门。
偶然“工作”。 var
所指的空间不再是你的空间,但这一次你已经逃脱了访问它。它可能导致分段错误,返回50以外的数字,或重新格式化您的硬盘。
请记住,似乎工作是未定义行为可以表现出来的一种可能方式。
答案 1 :(得分:3)
删除对象不会清除内存。在内存用于其他内容之前,该值仍将存在。所以它可能会工作一段时间......
某些C ++实现具有“调试模式”,可以为所有已删除的内存设置特定值,以检测此类错误。
答案 2 :(得分:2)
当您删除a时,您正在释放内存并允许后一个新内存覆盖它。在此之前,已删除对象中的所有变量仍在内存中,但可以随时覆盖。
答案 3 :(得分:1)
由于const
关键字,这非常棘手。
是的,在这种情况下你可能正在阅读未初始化的内存。对此的一些想法:
_a
的内容,因为标记为const
不是堆分配的,也不是堆栈分配但位于应用程序的DATA
部分,所以引用可能确实是仍然有效,不仅仅是偶然。static const
变量。您可能会考虑编写自定义内存管理器或研究编译器的调试模式行为,因为这非常非常重要。例如,Visual Studio会将变量设置为0xCDCDCDCD
。您还可以在数组末尾找到有趣的值,例如0xDEADC0DE
。