c++ - 调用析构函数后访问对象
问题描述
在下面的代码中,我~destructor()
显式调用了。但是,该对象仍然是可访问的。我怎样才能删除它(让它消失)?
class Queue {
public:
node* top = NULL;//points to the top of the queue
//methods:
void enqueue(int data);//adds a node to the queue
void dequeue();
//printing
void print();
//destructor
~Queue();
};
和析构函数:
Queue::~Queue() {
//The destructor deletes all items from HEAP
//Then sets the top to 0
while (top != NULL)
this->dequeue();//dequeue until there are NO more items
top = 0;
}
在 Source.cpp 中:
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);
q.dequeue();
q.dequeue();
q.print();
q.~Queue();
q.print();//Here I need to have an ERROR!
q.enqueue(7);//Here I need to have an ERROR!
q.print();//Here I need to have an ERROR!
输出是:
4 3 7
我期待一个错误:
标识符“q”未定义
解决方案
从//Here I need to have an ERROR!
字面上看,这是您将如何做到的:
{
Queue q;
q.enqueue(1);
q.enqueue(2);
q.dequeue();
q.print();
}
q.print(); // THIS WILL PRODUCE AN ERROR
您似乎对堆栈分配对象的生命周期有误解。堆栈对象超出范围时会自动销毁。在示例中,范围q
以}
.
自己调用析构函数几乎总是错误的(我遇到过一种可以显式调用析构函数的情况)。为什么?考虑一下:
{
Queue q;
q.~Queue(); // DONT DO THIS !
}
您调用了析构函数,但是当它超出范围时,它会再次被销毁,并且您将遇到令人讨厌的运行时错误。
您在代码中执行的操作:
Queue q;
q.~Queue();
q.print();
是未定义的行为!
另请注意,在删除对象时调用析构函数并不是全部。当堆栈分配的对象被删除时,首先调用它的析构函数,然后释放分配的内存。通常你不想干扰这个过程,幸运的是你很少需要这样做。
我怎样才能删除它(让它消失)?
你不能让它“消失”。当一个对象被销毁时,内存中的位和字节不会被擦除。那将是非常低效的。实际上,我认为 Cfree
有一个更好且更容易混淆的名称。内存被释放以供以后使用,它不会被清除,以至于无法读取之前的内容。
为了进一步阅读,我向您推荐这个关于一个稍微不同但相关的问题的详尽答案:可以在其范围之外访问局部变量的内存吗?
另外,我建议您阅读依赖于自动调用析构函数的RAII 。
TL;DR:如果你想清除Queue
然后写:
q.clear();
q.print(); // prints an empty queue!
永远不要调用堆栈分配对象的析构函数!它将被自动调用。
推荐阅读
- c# - Xamarin iOS 上此平台异常不支持操作
- javascript - 如何确保首先运行 Jest 引导文件?
- user-interface - JavaFX:将节点拖入 HBox
- python - 通过使其重新加载另一个函数来腌制一个用于多处理的函数
- html - XSLT 将属性值评估为 XPath?
- sql - 聚合函数将多行中的值汇总到一个结果行中
- angular - 在 Angular 9 上重新编译后缺少 @Input() 变量
- wordpress - 从 wordpress 中的日期中删除链接
- android - 将项目添加到 GitHub
- javascript - 创建自定义 Web 组件并在不同的框架中共享它