Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 自删除QoObject的最佳方法_C++_Qt_Qobject_Self Destruction - Fatal编程技术网

C++ 自删除QoObject的最佳方法

C++ 自删除QoObject的最佳方法,c++,qt,qobject,self-destruction,C++,Qt,Qobject,Self Destruction,我有两个类Node和NodeContainer: 类节点:公共QObject { 节点容器*父节点; } 类节点容器:QObject { bool deleteChild(节点*子节点) { 如果(子节点->删除(子节点)) { 儿童; } } QList子节点; } 节点可以有父节点,也可以没有父节点。 实现节点类销毁的更好方法是什么: 1) 访问家长并从那里摧毁自己 destroy() { 如果(父项!=0) { parent.deleteChild(本); } 其他的 { 后来(这个);

我有两个类Node和NodeContainer:

类节点:公共QObject
{
节点容器*父节点;
}
类节点容器:QObject
{
bool deleteChild(节点*子节点)
{
如果(子节点->删除(子节点))
{
儿童;
}
}
QList子节点;
}
节点可以有父节点,也可以没有父节点。 实现节点类销毁的更好方法是什么:

1) 访问家长并从那里摧毁自己

destroy()
{
如果(父项!=0)
{
parent.deleteChild(本);
}
其他的
{
后来(这个);
}
}
2) 发出一个信号,让父代稍后销毁它

destroy()
{
如果(父项!=0)
{
//一旦父项收到,父项将删除子项。
您必须删除技术文档(此文档);
}
其他的
{
后来(这个);
}
}
使用智能指针

class Node: public QObject
{
    std::unique_ptr<Node> parent;
}
类节点:公共QObject
{
std::唯一的父项;
}
如果指定给父指针,它将在销毁时删除,如果不指定,则不会发生任何事情:)

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

std::list<std::unique_ptr<node> > node_list;
std::列表节点\u列表;
可以输入到哪一个

typedef std::unique_ptr<node> node_up_t;
typedef std::list<node_up_t>  node_list_t;
typedef std::unique\u ptr node\u up\t;
typedef std::列表节点\u列表\t;
还是更好的

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


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

如果您必须删除的
父项
信号连接到
删除子项
插槽,那么您介绍的两种方法实际上没有区别。在调用插槽之前,程序不会返回事件循环

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

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

从QObject派生节点和节点容器。QObject已经具有用于自动删除子对象或从父对象中删除已删除子对象的功能和内置功能。只需利用现有机制,而不是重新发明轮子。

我会做1),但在节点的析构函数中,即

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

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


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

让父级连接到其子级的
销毁
信号,如果子级通过
deleteLater
销毁,则设置指针。那就不需要检查家长了。而且,你的计划看起来很奇怪。你确定这就是你想要的吗?我正在做一个小文本编辑器(带标签)。如果一个标记被删除,那么它需要请求包含该标记的标记将其删除。例如(Bla-Bla-more-Bla-Bla-Bla)。如果决定删除,它必须要求tag1将其从其子对象列表中删除。你确定不想使用而不是编写自己的数据结构吗?更多的是关于对象如何通知父对象其删除,然后是关于如何删除对象本身。这听起来像是反向设计,当然,父节点应该拥有子节点,并且父节点应该告诉子节点它将被销毁。但是他的节点本身正在存储对象,并且不使用QObject父节点存储机制。此外,由于必须执行所有强制转换,因此使用QObject父对象机制来管理树可能会很乏味。@pmr:“他的节点”不需要存储父对象,因为它可以通过
QObject::parent()
访问。重用现有机制将比实现另一个机制花费更少的时间,不管“繁琐”。此外,可以将强制类型转换包装到一两个内联方法中。