【问题标题】:Defining own destructor although class derives from QObject?尽管类派生自QObject,但定义自己的析构函数?
【发布时间】:2016-01-18 20:09:52
【问题描述】:

让我们有一个班级Test 和一个班级AnotherClass。两者都派生自 QObject。

测试.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;
}

Test-instance 被销毁时应该自动销毁other,因为Testother 的父级,对吧?

  • 现在我应该自己删除~Test() 中的other,还是因为它尝试删除同一个对象两次而使程序处于未定义阶段?
  • 这里的正确方法是什么?

【问题讨论】:

  • 你的析构函数应该是虚拟的。
  • @KoVadim - 因为 QObject 有虚拟析构函数,他的析构函数已经隐含虚拟了..
  • 删除other后为什么不在代码中添加delete this??? QObjects 是否会在没有明确的delete 字样的情况下自动删除,即使它们没有父对象?

标签: c++ qt


【解决方案1】:

QObjects 在对象树中组织自己。当您以另一个对象为父对象创建 QObject 时,该对象将自动将自身添加到父对象的 children() 列表中。父级获得对象的所有权;即,它将自动删除其析构函数中的子级。请参阅Object Trees & Ownership 了解更多信息。

因为您将 Test 对象的 this 指针传递给 AnotherClass 构造函数,这意味着您使用 Test 对象作为AnotherClass 的父级。因此,删除 Test 对象也会删除它的子对象,并且您不需要显式删除 其他

但是,在这种情况下,在析构函数中显式删除不会导致双重删除,因为它会导致从父级的 children() 列表中注销

【讨论】:

    【解决方案2】:

    除了你必须创建析构函数virtual,Qt 文档说:

    QObjects 在堆上创建时(即用new 创建),一棵树 可以以任何顺序从它们构造,然后, 这棵树可以按任何顺序销毁。当树中有任何QObject 被删除,如果对象有父对象,析构函数自动 从其父对象中删除对象。如果对象有子对象,则 析构函数自动删除每个孩子。否 QObject 已删除 两次,无论破坏顺序如何。

    所以你可以明确地delete other 类,但你不必这样做。任何一种方法都应该在没有双重 deletes 的情况下工作。

    顺便说一句,您还可以将AnotherClass 设为Test 的简单成员,而不是指针。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 2018-01-24
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 2016-01-18
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多