在创建QObject对象的时候,可以提供一个父对象,我们创建的这个QObject对象的时候会自动添加到其父对象的children()列表。当父对象析构的时候,这个列表的所有对象都会被析构。
- #include
- #include
-
- using namespace std;
- class Object;
- typedef list
-
- class Object
- {
- public:
- Children children;
- Object(Object* parent=nullptr)
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- }
-
- virtual ~Object()
- {
- for(auto it=children.begin();it!=children.end();it++){
- delete *it;
- }
- }
- };
-
- class A:public Object
- {
- public:
- A(Object* parent=nullptr)
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- cout<<"A的构造"<
- }
-
- ~A()
- {
- cout<<"A的析构"<
- }
- };
-
-
- int main()
- {
- Object obj;
-
- A* a=new A(&obj);
- return 0;
- }
3.自己写的时候注意点:
3.1父类中的析构一定要加virtual形成多态,不然即使A中的地址是被释放了,但是释放的类型是Object的类型,并不会条用A中的析构,这样就很危险,如果当A中有一个指针的时候,就没法释放,造成内存泄漏,而且此时因为a的地址已经被隐式强转了,所以再次删除删除的是Object类型,所以Object类型会被调用两次析构。
- #include
- #include
-
- using namespace std;
- class Object;
- typedef list
-
- class Object
- {
- public:
- Children children;
- Object(Object* parent=nullptr)
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- }
-
- ~Object()
- {
- for(auto it=children.begin();it!=children.end();it++){
- delete *it;
- *it=nullptr;
-
- }
- cout<<"Object的析构"<
-
- }
- };
-
- class A:public Object
- {
- public:
- A(Object* parent=nullptr)
-
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- cout<<"A的构造"<
- }
-
- ~A()
- {
- cout<<"A的析构"<
- }
- };
-
-
- int main()
- {
- Object obj(nullptr);
-
- A* a=new A(&obj);
- return 0;
- }
结果图:

3.2这是我当时自己犯的错误,代码如下:
- #include
- #include
-
- using namespace std;
- class Object;
- typedef list
-
- class Object
- {
- public:
- Children children;
- Object(Object* parent)
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- }
-
- virtual ~Object()
- {
- for(auto it=children.begin();it!=children.end();it++){
- delete *it;
- *it=nullptr;
-
- }
- cout<<"Object的析构"<
-
- }
- };
-
- class A:public Object
- {
- public:
- A(Object* parent=nullptr):Object(parent)
- {
- if(parent!=nullptr){
- parent->children.push_back(this);
- }
- cout<<"A的构造"<
- }
-
- ~A()
- {
- cout<<"A的析构"<
- }
- };
-
-
- int main()
- {
- Object obj(nullptr);
-
- A* a=new A(&obj);
- return 0;
- }
结果图:

3.2.1分析:
如图所示:当父类调用过一次后,删除了Object的类型的a的地址,按照我们上面的理解一个还会再调用一次析构,但是当析构过一次后,它直接报错了,这是为什么呢?当我们 在A中进行初始化的时候,如果按照开头我们写的那种正确方法,其实是给parent初始化为nullptr,但是当我们3.2这种写法的时候,初始化的并不是nullptr,而是a的地址,所以我们在父类中也将a中的地址放进了list中,在A中也将a的地址放进了list中,所以在条用父类中的析构的时候,我们释放了两次一模一样的地址,所以肯定会报错。
-
相关阅读:
华为mate60 上线 媒介盒子多家媒体报道
Kubernetes 的亲和性污点与容忍
计算机二级--java篇
JVM源码解析
Selenium 是什么?简单了解Selenium
【YOLO系列】YOLOv9论文超详细解读(翻译 +学习笔记)
【理论】车辆双轴振动模型(一)
【node】初识node以及fs操作,path操作以及http操作(一)
入坑计算机视觉必备的图像基础
unity URP 利用particle system制作简单的shader交互
-
原文地址:https://blog.csdn.net/a2998658795/article/details/126146605