虚析构函数

还是一篇有关虚函数的文章,这次是解析虚析构函数的。先直接上代码吧。

[cpp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3. class A  
  4. {  
  5.      public:  
  6.     int a;  
  7.     A() { cout<<"A"<<endl; }  
  8.     ~A(){ cout<<"~A"<<endl; }  
  9. }  
  10. class B  
  11. {  
  12.      public:  
  13.     A *pA;  
  14.     B() {   
  15.            pA = new A();  
  16.        cout<<"B"<<endl;  
  17.     }  
  18.     virtual ~B() {  
  19.        delete pA;  
  20.        cout<<"~B"<<endl;  
  21.     }  
  22. }  
  23. class C : public B  
  24. {  
  25.       public:  
  26.     C():B() { cout<<"C"<<endl; }  
  27.     ~C() { cout<<"~C"<<endl; }  
  28. }  
  29. int main() {  
  30.       B* pB = new C;  
  31.       delete pB;  
  32.       return 0;  
  33. }  

运行结果:若19行没有virtual:A   B   C  ~A  ~B
                若19行有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的析构函数。

后来还遇到一种情况,如下:

[cpp]  view plain copy
  1. class CA  
  2. {  
  3. public:  
  4.  CA(){cout<<"CA constructor"<<endl;}  
  5.    
  6.     ~CA(){cout<<"CA desstructor"<<endl;}  
  7. };  
  8. class CB:public CA  
  9. {  
  10. public:  
  11.  CB(){cout<<"CB constructor"<<endl;}  
  12.    
  13.  ~CB(){cout<<"CB desstructor"<<endl;}  
  14. };  
  15. class CC:public CB  
  16. {  
  17. public:  
  18.  CC(){cout<<"CC constructor"<<endl;}  
  19.    
  20.  ~CC(){cout<<"CC desstructor"<<endl;}  
  21. };  
主函数为:
[cpp]  view plain copy
  1. int main()  
  2. {  
  3.    CA * p = new CC();  
  4.    delete p;  
  5.    return 0;  
  6. }  
的时候,输出的结果如下:
CA constructor
CB constructor
CC constructor
这种情况是,没有调用析构函数,直接把申请的内存给释放了。






本文出自 “cesc” 博客,请务必保留此出处http://blog.csdn.net/jiangyi711/article/details/4804356


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值