自我删除QObjects的最佳方法

时间:2012-03-01 19:21:52

标签: c++ qt qobject self-destruction

我有两个类Node和NodeContainer:

class Node: public QObject
{
    NodeContainer* parent;
}

class NodeContainer : QObject
{
    bool deleteChild(Node*child)
    {
        if(childNodes->remove(child))
        {
            deleteLater(child);
        }
    }

    QList<Node*> childNodes;
}

节点可以拥有父节点。 实现Node类销毁的更好方法是什么:

1)访问父母并从那里摧毁自己

destroy()
{
    if(parent !=0)
    {
        parent.deleteChild(this);
    }
    else
    {
        deleteLater(this);
    }
}

2)发出一个信号,让父母稍后将其销毁

destroy()
{
    if(parent !=0)
    {
        //Once the parent receives it, the parent will delete the child.
        emit parentYouHaveToDeleteChild(this);
    }
    else
    {
        deleteLater(this);
    }
}

4 个答案:

答案 0 :(得分:1)

如果parentYouHaveToDeleteChild信号连接到deleteChild广告位,则您提供的两种方法实际上没有区别。在调用插槽之前,程序不会返回事件循环。

除了第二种方法增加了信号/槽调用的开销。

答案 1 :(得分:1)

Object Trees and ownership

  

您也可以自行删除子对象,并将自己从父母身上删除。例如,当用户删除工具栏时,可能会导致应用程序删除其中一个QToolBar对象,在这种情况下,工具栏的QMainWindow父级会检测到更改并相应地重新配置其屏幕空间。

您从QObject派生Node和NodeContainer。 QObject已经具有parent()功能和内置object tree,用于自动删除子项或从父项中删除已删除的子项。只需利用现有的机制,而不是重新发明轮子。

答案 2 :(得分:0)

使用智能指针

class Node: public QObject
{
    std::unique_ptr<Node> parent;
}

如果您指定父指针,它将在销毁时删除,如果不指定,则不会发生任何事情:)

我还建议使用列表中的智能指针:

std::list<std::unique_ptr<node> > node_list;

可以是typedeffed to

typedef std::unique_ptr<node> node_up_t;
typedef std::list<node_up_t>  node_list_t;

或更好的东西

这样,当从列表中删除元素时,它将自动被删除,列表被销毁时也是如此。

对于非UI代码,我强烈建议您使用标准容器,因为它们是标准容器并减少对库的依赖。

答案 3 :(得分:0)

我会做1),但是在Node的析构函数中,即

class Node: public QObject
{
public:
    ~Node ()
    {
        if(parent !=0)
        {
            parent.deleteChild(this);
        }
    }

    NodeContainer* parent;
}

我认为对于“自杀”的对象来说,这不是一个好的OO练习。创建Node的对象也应该删除它们,并且通过析构函数,它们也将从它们潜在的NodeContainer中删除。

请注意,如果您不使用信号/插槽或Qt父级机制,那么使您的对象成为QObject的后代几乎没有意义。它增加了开销而没有任何好处。