我有两个类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);
}
}
答案 0 :(得分:1)
如果parentYouHaveToDeleteChild
信号连接到deleteChild
广告位,则您提供的两种方法实际上没有区别。在调用插槽之前,程序不会返回事件循环。
除了第二种方法增加了信号/槽调用的开销。
答案 1 :(得分:1)
您也可以自行删除子对象,并将自己从父母身上删除。例如,当用户删除工具栏时,可能会导致应用程序删除其中一个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的后代几乎没有意义。它增加了开销而没有任何好处。