虚析构函数
来源:互联网 发布:秃子扳机数据图 编辑:程序博客网 时间:2024/05/16 06:51
所谓虚析构函数就是用virtual关键字修饰的析构函数。比如:
Class A
{
public:
virtual ~A();
};
这样的就是虚析构函数。
那么就出现了一个问题,为什么要使用虚析构函数呢?请看下面这个例子:
class A
{
public:
A();
~A();
};
A::A()
{
cout<<”A()”<<endl;
}
A::~A()
{
cout<<”~A()”<<endl;
}
class B : public A
{
public:
B();
~B();
};
B::B()
{
cout<<”B()”<<endl;
}
B::~B()
{
cout<<”~B()”<<endl;
}
int main()
{
A *pa;
B *pb;
pb = new B;
pa = pb;
delete pa;
return 0;
}
发动你那上帝赐予的智商高达300的大脑思考一下,这段看似简单的程序的输出结果是什么。再去自己编程验证一下,看计算机的大脑和你的是否一样。
如果猜的不错的话(这显然是废话啊),是不是很多人猜想会输出:
A()
B()
~B()
~A()
那只有恭喜你又取得了进步,因为你猜错了!程序的实际输出结果是:
A()
B()
~A()
是不是很诡异啊?明明是调用了B的构造函数,却没有调用到B的析构函数。不会是编译器出问题了吧?告诉你一个真理,写编译器的哥们儿不是一般的高手,他们是很牛的一群人。至于牛到什么程度,反正不是你我在目前这个阶段能望其项背的,所以不用怀疑编译器。程序之所以输出这样的结果,是因为试图通过一个基类型的指针来删除派生类对象。释放这个指针所指向的内存区域时,只会调到基类A的析构函数,这就是语法规则。
这肯定不是我们想要的啊,因为通常情况下B的析构函数肯定不是这么简单(实际上这只析构函数是没有意义的,举例需要啊),里面通常是是释放构造函数申请的内存,调不到B的析构,就造成了内存泄露了。怎么解决这个问题呢?
这就到重点了(说了这么多才到重点,正是绕啊!汗~~~),利用虚析构就可以解决这个问题。在A的析构函数之前添加virtual关键字即可。自己验证一下,可以看到输出结果为:
A()
B()
~B()
~A()
- 虚析构函数、纯虚析构函数
- 虚析构函数,纯虚析构函数~~~
- 构造函数 虚函数 虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 纯虚函数、虚函数、虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚函数,虚析构函数,虚函数表
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 内存泄露与内存溢出总结
- 把SEH类型的系统异常转化为C++类型的异常
- 学习Python
- Hibernate多对多
- Azure Basic - Insert data into BlockBlob, Table and Queue (with Diagnostic + Azure Storage Explore)
- 虚析构函数
- 新浪微博应用地址
- 分析HTML5在移动开发方面的发展状况
- ext动态加载树
- 版本控制工具git的安装和常用命令
- 应用程序域
- python实现人人网的自动登录
- Attribute theme invalid for tag head according to TLD
- Thrift 学习笔记2——Windows环境下Thrift的安装、编译以及测试