Cpp: 析构调用顺序(父类指针指向子类对象,内存泄漏问题)

51 篇文章 2 订阅

from:https://blog.csdn.net/weixin_33779515/article/details/93275438

class A {
public:
A() { printf("A \n"); }
~A() { printf(" ~A \n"); } // 这里不管写不写virtual,删除B对象的时候,都会被执行。因为这个例子是B*指针指向B对象,不是A*指针指向B对象。
};

class B : public A
{
public:
B() { printf("B \n"); }
~B() { printf("~B \n"); }
};

int main(int argc, char* argv[])
{
B* b = new B;

delete b;
return 0;
}
int main(int argc, char* argv[])
{
B b; // 虽然正确,但其实是非正常情况,因为你防不住程序员定义A* a = new B(); 这样就错了。
return 0;
}
执行结果:
A
B
~B
~A

结论:删除子类指针,无论如何会自动调用祖先类的析构函数(即使祖先类的析构函数不是虚拟的),虽然这是非正常情况,但还是记一下。

------------------------------------------------------------

class A {
public:
A() { printf("A \n"); }
virtual ~A() { printf(" ~A \n"); } // 增加了虚拟关键字
};

class B : public A
{
public:
B() { printf("B \n"); }
~B() { printf("~B \n"); }
};

int main(int argc, char* argv[])
{
A* a = new B;

delete a;
return 0;
}
执行结果(正常情况,子类祖先类的析构函数都是虚拟的,这样删除祖先类指针、子类对象的时候,可正确同时调用子类和祖先类的析构函数):
A
B
~B
~A
但是如果去掉 virtual(这里是A*指针指向B对象),改一下立刻有效果,变成了错误(错误情况)。
执行结果:
A
B
~A

总结:自己类型的指针指向自己的对象,怎么样都没有问题(不管父类析构函数写不写virtual)。只有基类指针指向子类对象的时候,一定需要【父类】virtual关键字的配合,才能正确的工作

 

添加测试:

#include <stdio.h>
#include <iostream>

using namespace std;

class A {
public:
    int a;
A() { printf("A \n"); }
~A() { printf(" ~A \n"); } // 这里不管写不写virtual,删除B对象的时候,都会被执行。因为这个例子是B*指针指向B对象,不是A*指针指向B对象。
};
 
class B : public A
{
public:
    int b;
B() { printf("B \n"); }
//virtual ~B() { printf("~B \n"); }} !!!!! ==> sigtrap fatal error ===> if only virtual ~B() ==> ~A() will be called first then ~B()will be attempted
~B() { printf("~B \n");}
};
 
int main(int argc, char* argv[])
{
B* b = new B;
 cout << b->a << " " << b->b << endl;
delete b;

//below cannot be compiled ===> A does not have member b
/*
A* a = new B();
cout << a->a << " " << a->b << endl;
delete a;

A* a_1 = new B;
cout << a_1->a << " " << a_1->b << endl;
delete a_1;
*/
A* a = new B();
cout << a->a << endl;
delete a;

A* a_1 = new B;
cout << a_1->a << endl;
delete a_1;

B b_1; // 虽然正确,但其实是非正常情况,因为你防不住程序员定义A* a = new B(); 这样就错了。【参见https://blog.csdn.net/a2796749/article/details/46908035】==》实测并无问题==》只牵扯初始化
cout << b_1.a << " " << b_1.b << endl;

return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值