【发布时间】:2012-02-07 00:57:32
【问题描述】:
在删除对象后进入析构函数之前,什么会使字段变量过时? 我正在寻找这个问题的答案,我在这个网站上遇到了这个问题: Lifetime of object is over before destructor is called?
有些东西根本没有加起来:如果我在另一个 WrapperClass 中声明了一个指向 SomeClass 的指针,那么当我构造 WrapperClass 时,我需要创建一个 new SomeClass 和 delete 它包装的破坏。
这是有道理的,并且到目前为止一直有效。
指针在析构函数中仍然有效且正确,否则显然我无法删除它。
现在我的问题是,当我调用析构函数时,WrapperClass 的字段成员(一个 int 和一个指向 SomeClass 数组的指针)是垃圾。我在构造后检查了包装器对象,数据很好。包装器实际上是另一个Main 类中的指针,当我破坏Main(破坏包装器)时会出现问题,但如果我只是delete 来自Main 中的另一个方法的包装器,则工作正常。
我的偏执使我得到了上述答案,现在我完全糊涂了。
有人想了解一下这里到底发生了什么吗?
编辑:
Node 是 SomeClass。
class WrapperException{};
class Wrapper {
private:
struct Node { /*....*/ };
int numNodes;
Node** nodes;
public:
Wrapper() : numNodes(0) { nodes = new Node*[SIZE]; }
Wrapper(const Wrapper& other) { throw WrapperException(); }
Wrapper& operator=(const Wrapper& other) { throw WrapperException(); }
~Wrapper() { //calling delete Main gets me here with garbage for numNodes and nodes
for(int i = 0; i < numNodes; i++)
delete nodes[i];
delete nodes;
}
};
class MainException{};
class Main {
public:
Main() { wrapper = new Wrapper(); }
Main(const Main& other) { throw MainException(); }
Main& operator=(const Main& other) { throw MainException(); }
~Main() { delete wrapper; }
private:
Wrapper* wrapper;
};
【问题讨论】:
-
你不是唯一一个困惑的人。向我们展示一些代码而不是描述它可能会有所帮助(请仅提供相关部分)。但只是一个想法:你没有打破三规则,是吗?
-
如果你有一个非平凡的析构函数,你是否确保在所有构造函数中都初始化了资源?另外:请输入代码。
-
@Grizzly 我不是 3 规则的专家,但我认为它甚至不适用于这个非常简单的情况,不是吗?
-
在调试器中运行,并在
Wrapper析构函数中设置断点。然后你会看到它是否被调用了两次,这可能是问题之一。另一件事可能是您以某种方式使用了非法指针,例如超出列表或数组末尾的一步。 -
@JoachimPileborg 我在
Main的析构函数处设置了一个断点,该断点立即与垃圾一起进入Wrapper的析构函数...
标签: c++ destructor