信誉好的网站建设公司,多个wordpress网站合并,小程序定制公司有哪些,在线旅游网站平台有哪些一. QT对象树的概念
QObject 的构造函数中会传入一个 Parent 父对象指针#xff0c;children() 函数返回 QObjectList。即每一个 QObject 对象有且仅有一个父对象#xff0c;但可以有很多个子对象。
那么Qt这样设计的好处是什么呢#xff1f;很简单#xff0c;就是为了方…一. QT对象树的概念
QObject 的构造函数中会传入一个 Parent 父对象指针children() 函数返回 QObjectList。即每一个 QObject 对象有且仅有一个父对象但可以有很多个子对象。
那么Qt这样设计的好处是什么呢很简单就是为了方便内存管理。在创建QObject对象时可以提供一个父对象我们创建的这个QObject对象会自动添加到其父对象的children()列表当父对象析构的时候这个列表的所有对象也会被析构。当析构子对象的时候会自动从父对象的子对象列表中删除。
当一个Q0bject对象在堆上创建的时候Qt会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的。这意味着销毁这些对象的顺序也是未定义的。任何对象树中的Q0bject对象delete的时候如果这个对象有 parent,则自动将其从parent的children()列表中删除;如果有孩子则自动delete 每一个孩子。Qt 保证没有 Q0bject 会被 delete 两次这是由析构顺序决定的。
如果 Q0bject 在栈上创建Qt 保持同样的行为。正常情况下这也不会发生什么问题。来看下下面的代码片段:
{QWidget window;QPushButton quit(Quit,window);
}
作为父组件的 window 和作为子组件的 quit 都是 Q0bject 的子类(事实上它们都是 QWidget 的子类而 QWidget是Q0bject 的子类)。这段代码是正确的,quit 的析构函数不会被调用两次因为标准 C要求局部对象的析构顺序应该按照其创建顺序的相反过程。因此这段代码在超出作用域时会先调用 quit的析构函数将其从父对象window的子对象列表中删除然后才会再调用window 的析构函数。
二. 使用纯C实现QT对象树内存回收机制底层原理
#include iostream
#include list
using namespace std;
class Object;
typedef listObject* ObjectList;class Object
{
public:ObjectList children_List;Object(Object* parent nullptr){if(parent ! nullptr){parent-children_List.push_back(this);}}//为了保证使用多态时子类对象无法释放的问题所以加一个virtualvirtual ~Object(){for(auto it children_List.begin(); it ! children_List.end(); it){delete *(it);}}
};class A : public Object
{
public:A(Object* parent nullptr){if(parent ! nullptr){parent-children_List.push_back(this);}coutA gouzaoendl;}~A(){coutA xigouendl;}
};class B : public Object
{
public:B(Object* parent nullptr){if(parent ! nullptr){parent-children_List.push_back(this);}coutB gouzaoendl;}~B(){coutB xigouendl;}
};int main()
{
// Object obj;
// A* a new A(obj);B b;A* a new A(b);//new A是一个继承的子类对象 b父类的指针 也就是b的孩子列表中装入了A这个对象 B和A不是继承关系//不需要指针也不需要delete内存就能被完整的释放掉return 0;
}virtual 为了保证使用多态时子类对象无法释放的问题所以加一个virtual
auto 是自动类型判断