虚析构函数
来源:互联网 发布:托尼阿伦防守科比数据 编辑:程序博客网 时间:2024/05/21 23:33
解析虚析构函数
#include <iostream>
using namespace std;
class A
{
public:
int a;
A() { cout<<"A"<<endl; }
~A(){ cout<<"~A"<<endl; }
}
class B
{
public:
A *pA;
B() {
pA = new A();
cout<<"B"<<endl;
}
virtual ~B() { // 第18行
delete pA;
cout<<"~B"<<endl;
}
}
class C : public B
{
public:
C():B() { cout<<"C"<<endl; }
~C() { cout<<"~C"<<endl; }
}
int main() {
B* pB = new C;
delete pB;
return 0;
}
运行结果:若18行没有virtual:A B C ~A ~B
若18行有virtual: A B C ~C ~A ~B
这个结果说明,如果类B被类C继承,而且用父类的指针指向其子类对象(比如:B *bB = new C;)时,那么父类B的析构函数必须是虚的,否则在delete bB的时候,只会调用父类B的析构函数,子类C的析构函数不会被调用。这样会造成内存泄露。
构造函数的工作方式:先调用父类的构造函数,再调用派生类的构造函数。
析构函数的工作方式:先调用派生类的析构函数,再调用每一个父类的析构函数。
如果层次中根类的析构函数是虚函数,则派生类的虚构函数也将是虚函数 ,无论派生类显式定义析构函数还是使用合成析构函数,派生类的析构函数都是虚函数。这样就说明了下面的问题,因为B的析构函数是虚函数,那么C的虚构函数也是虚函数,这样,~B和~C都存在于C的虚表之中,在B *pB = new C;的时候,将C的虚表浅拷贝到了B类指针指向的区域,那么在delete pB;的时候,自然会调用到 ~C和 ~B。
从上面这张图片可以看出,在B *pB = new C;这一步时,C对象的虚函数表被浅拷贝到B对象的虚函数表 。从而delete pB;的时候,调用了C的析构函数。
后来还遇到一种情况,如下:
class CA
{
public:
CA(){cout<<"CA constructor"<<endl;}
~CA(){cout<<"CA desstructor"<<endl;}
};
class CB:public CA
{
public:
CB(){cout<<"CB constructor"<<endl;}
~CB(){cout<<"CB desstructor"<<endl;}
};
class CC:public CB
{
public:
CC(){cout<<"CC constructor"<<endl;}
~CC(){cout<<"CC desstructor"<<endl;}
};
主函数为:
int main()
{
CA * p = new CC();
delete p;
return 0;
}
的时候,输出的结果如下:
CA constructor
CB constructor
CC constructor
这种情况是,没有调用析构函数,直接把申请的内存给释放了。
- 虚析构函数、纯虚析构函数
- 虚析构函数,纯虚析构函数~~~
- 构造函数 虚函数 虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 纯虚函数、虚函数、虚析构函数
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚函数,虚析构函数,虚函数表
- 虚析构函数、纯虚析构函数、虚构造函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- 虚析构函数
- vc++
- 12
- DataGridView不产生多余的列
- 关于tomcat关闭时错误信息Failed shutdown of Apache Portable Runtime的解决方法
- Android 关于 Activity 之间的切换动画
- 虚析构函数
- 我的《婚房》呢?迷茫呀!!!!!!
- Android屏幕切换效果实现
- win7自动锁定问题
- wan
- 2011.06.13
- Eclipse 常用快捷键
- android实验四 QR码生成器的设计与实现
- GridView无数据时.仍然显示表头.