1

我有两个类 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

4 回答 4

1

If the parentYouHaveToDeleteChild signal is connected to the deleteChild slot, there is effectively no difference between the two methods you've presented. The program will not return to the event loop before calling the slot.

Except that the second method adds the overhead of a signal/slot call.

于 2012-03-01T19:35:32.900 回答
1

对象树和所有权

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

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

于 2012-03-01T20:10:18.190 回答
0

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

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

    NodeContainer* parent;
}

我不认为对象“自杀”是一种好的 OO 实践。创建节点的对象也应该删除它们,并且通过析构函数,它们也将从潜在的 NodeContainer 中删除。

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

于 2012-03-02T00:34:40.503 回答
0

使用智能指针

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

如果您分配给父指针,它将在销毁时删除,如果您不这样做,则不会发生任何事情:)

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

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

可以输入到

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

或者更好的东西

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

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

于 2012-03-01T19:32:30.093 回答