为什么这有效?返回 C++ 中的 const 引用
我在玩弄 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 时,它不再包含有效的引用,并且应该发生分段错误。
为什么这有效?我不相信我制作了临时副本。
I am fooling around with C++ and const references and am confused why this code works:
#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;
}
Result:
50
50
Here are my thoughts:
var stores a reference to a_.
when a is deleted, a_ should also be deleted.
when var is accessed again, it no longer contains a valid reference and a segmentation fault should occur.
Why does this work? I do not believe I make a temporary copy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您删除
a
时,访问var
就成为您进入未定义行为领域的大门。这是偶然的“工作”。
var
所指的空间不再属于您,但这次您成功地访问了它。它可能会导致分段错误、返回 50 以外的数字或重新格式化您的硬盘驱动器。请记住,看似有效是未定义行为表现出来的一种可能方式。
The moment you deleted
a
, accessingvar
became your door into undefined behavior land.It's "working" by chance. The space where
var
was one referring to is no longer yours, but you got away with accessing it, this time. It could have resulted in a segmentation fault, returned a number other than 50, or reformatted your hard drive.Remember, seeming to work is one possible way undefined behavior can manifest itself.
删除对象并不会清除内存。该值将一直存在,直到内存被用于其他用途。所以它可能会工作一段时间......
一些 C++ 实现有一个“调试模式”,它为所有已删除的内存设置一个特定的值来检测这样的错误。
Deleting an object does not clear the memory. The value will still be there until the memory is used for something else. So it may work for a while....
Some C++ implementations have a "debug mode" that sets a particular value to all deleted memory to detect bugs like this.
当您删除一个内存时,您将释放内存并允许后面的新内存覆盖它。在此之前,已删除对象内的所有变量仍在内存中,但可能随时被覆盖。
When you delete a you are freeing the memory and allowing a latter new to override it. Until then all the variables inside your deleted object are still in memory, but may be overridden at any time.
由于
const
关键字的存在,这非常棘手。确实,在这种情况下您可能正在读取未初始化的内存。对此的一些想法:
_a< 的内容/code>,由于标记的 const 既不是堆分配的,也不是堆栈分配的,而是驻留在应用程序的 DATA 部分,因此引用可能确实仍然有效,不仅如此偶然。
[编辑]:这只适用于
static const
变量。您可能会考虑编写自定义内存管理器或研究编译器的调试模式行为,因为这非常非常重要。例如,Visual Studio 将变量设置为
0xCDCCDCD
。您还会在数组末尾发现有趣的值,例如0xDEADC0DE
。This is quite tricky because of the
const
keyword.True, you could be reading uninitialized memory in this case. Some thoughts on that:
The contents of[EDIT]: This can only be true for_a
, since markedconst
are not heap-allocated nor stack allocated but reside in theDATA
section of the application, so the reference might indeed be still valid, not only by chance.static const
variables.You might consider writing a custom memory manager or research on the debug mode behaviour of your compiler, because this is very, very important. Visual Studio will set variables to
0xCDCDCDCD
, for example. You will also find funny values such as0xDEADC0DE
at the end of arrays.