C++虚构函数的使用

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. class father  
  4. {  
  5. public:  
  6.     father():a(50){;}  
  7.     ~father(){cout<<"父亲的析构函数"<<endl;}  
  8.     int a;  
  9. };  
  10. class son:public father  
  11. {  
  12. public:  
  13.     son():b(50){;}  
  14.     ~son(){cout<<"儿子的析构函数"<<endl;}  
  15.     int b;  
  16. };  
  17. void main()  
  18. {  
  19.     father *p = new son;  
  20.     delete p;  
  21. }  
在main函数中如上代码所示,我们用一个父指针指向子类对象,然后用delete释放掉。这样会造成内存泄露吗?书上说,由于父指针指向了子对象,如果父类析构函数不声明为虚函数,那么,delete时,只会调用父类析构函数,不会调用子类析构函数。那么,可能造成内存泄露。上面的代码编译运行后发现,确实,子类析构函数并没有被调用。但会不会造成内存泄露呢?实践是检验真理的唯一标准,我把main函数里的代码改为:
[cpp]  view plain  copy
  1. system("pause");  
  2. father *p = new son[1000000];  
  3. delete []p;  
  4. system("pause");  

运行发现,内存并没有泄露。那为什么书上说可能泄露呢,注意,“可能!”。我把代码改为:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. class father  
  4. {  
  5. public:  
  6.     father():a(50){;}  
  7.     ~father(){;}  
  8.     int a;  
  9. };  
  10. class son:public father  
  11. {  
  12. public:  
  13.     son(){b=new int(50);}  
  14.     ~son(){delete b;}  
  15.     int *b;  
  16. };  
  17.   
  18. void main()  
  19. {  
  20.     system("pause");  
  21.     father *p = new son[1000000];  
  22.     delete []p;  
  23.     system("pause");  
  24. }  

运行后发现,内存泄露了!为什么呢?注意我们在子类构造函数了new了一个int,本来我们需要用子类析构函数来delete的,但是由于main函数里delete []p时只调用了父类析构函数,没有调用子类析构函数,所以子类析构函数里的delete没有执行,就内存泄露了。我们把上面代码改一改,在父类析构函数前加个virtual声明为虚函数。

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. class father  
  4. {  
  5. public:  
  6.     father():a(50){;}  
  7.     virtual ~father(){;}  
  8.     int a;  
  9. };  
  10. class son:public father  
  11. {  
  12. public:  
  13.     son(){b=new int(50);}  
  14.     ~son(){delete b;}  
  15.     int *b;  
  16. };  
  17.   
  18. void main()  
  19. {     
  20.     system("pause");  
  21.     father *p = new son[1000000];  
  22.     delete []p;  
  23.     system("pause");  
  24. }  

运行发现,并没有发生内存泄露!原来是这样,书上说的可能发生内存泄露,“可能”,注意是“可能”。当子类析构函数里有delete时,由于析构函数不是虚函数,main函数里的父指针指向的是子类对象,delete父指针时只调用了父类析构函数而没有调用子类析构函数,子类析构函数中的delete没有被执行,所以就内存泄露了。但析构函数声明为虚函数后,delete父指针时,既调用了子类析构函数也调用了父类析构函数。子类析构函数中的delete被执行,就没有发生内存泄露。


参考原文链接


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值