我们有一个班级Test
和一个班级AnotherClass
。两者都来自QObject。
Test.h:
class Test : public QObject
{
Q_OBJECT
public:
Test(QObject* parent);
~Test();
private:
AnotherClass* other;
};
class AnotherClass : public QObject
{
Q_OBJECT
public:
AnotherClass(QObject* parent);
~AnotherClass();
};
Test.cpp的:
Test::Test(QObject* parent) : QObject(parent)
{
other = new AnotherClass(this);
}
Test::~Test()
{
delete other;
}
other
- 实例被销毁后, Test
应自动销毁,因为Test
是other
的父级,对吗?
other
中自己删除~Test()
,还是将程序保留在未定义的阶段,因为它试图删除同一个对象两次?答案 0 :(得分:11)
QObjects 在对象树中组织自己。当您使用另一个对象作为父对象创建 QObject 时,该对象将自动将其自身添加到父 children()列表中。父母取得对象的所有权;即,它将自动删除其析构函数中的子项。有关详细信息,请参阅Object Trees & Ownership。
因为您将 Test 对象的 指针传递给 AnotherClass 构造函数,这意味着您使用 Test 对象作为 AnotherClass 的父级。因此,删除测试对象也会删除其子项,您不需要明确删除 其他。
但是,在这种情况下,析构函数中的显式删除不会导致双重删除,因为它会导致从父级的children()列表中取消注册。
答案 1 :(得分:4)
除了你必须制作析构函数virtual
之外,Qt文档说:
在堆上创建
QObject
时(即使用new
创建),树 可以按任何顺序从它们构造,然后在中构建 树可以按任何顺序销毁。当树中的任何QObject
时 删除,如果对象有父,则自动析构 从父对象中删除对象。如果对象有孩子,那么 析构函数会自动删除每个孩子。不会删除QObject
两次,无论破坏的顺序如何。
因此,您可以明确地delete
other
类,但您不必这样做。这两种方法都应该没有双delete
s。
顺便说一下,你也可以让AnotherClass
成为Test
的简单成员,而不是指针。