在创建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中,所以在条用父类中的析构的时候,我们释放了两次一模一样的地址,所以肯定会报错。
-
相关阅读:
使用WIX 进行商业智能OEM打包
squid代理服务器(传统代理、透明代理、反向代理、ACL、日志分析)
Kubernetes CRD 介绍
Aragon创建DAO polygon BSC测试网
【C++】继承和多态常见的问题
【无标题】
牛客网SQL160
文本分类微调技巧实战2.0
杭电oj 2059 龟兔赛跑 C语言
力扣第541题 反转字符串 II c++注释 双指针基础版
-
原文地址:https://blog.csdn.net/a2998658795/article/details/126146605