(GeekBand或极客班) 你的内存泄漏了--- 之 virtual 析构

来源:互联网 发布:炉石传说mac版下载 编辑:程序博客网 时间:2024/06/15 05:18

在这次作业点评中发现很多同学都没有在基类的析构函数使用virtual。

这在类的继承中是非常危险的。因为你的析构没有正确的调用,你的内存可能在不断的泄漏。。。

下面用一个小实验测试一下吧。

下面先给出测试代码:

Demo.h

#ifndef __DEMO_H__#define __DEMO_H__#include <iostream>class IBase1{public:IBase1() {std::cout<<"执行了 IBase1 的构造函数"<<std::endl;};~IBase1() {std::cout<<"执行了 IBase1 的析构函数"<<std::endl;};};class IBase2{public:IBase2() {std::cout<<"执行了 IBase2 的构造函数"<<std::endl;};virtual ~IBase2() {std::cout<<"执行了 IBase2 的析构函数"<<std::endl;};};class IDerive1 : public IBase1{public:IDerive1() {std::cout<<"执行了 IDerive1 的构造函数"<<std::endl;};~IDerive1() {std::cout<<"执行了 IDerive1 的析构函数"<<std::endl;};};class IDerive2 : public IBase2{public:IDerive2() {std::cout<<"执行了 IDerive2 的构造函数"<<std::endl;};~IDerive2() {std::cout<<"执行了 IDerive2 的析构函数"<<std::endl;};};#endif
main.h

#include <iostream>#include "Demo.h"int main(){std::cout<<"------------------------测试非虚析构"<<std::endl;IBase1* p1 = new IDerive1();delete p1;std::cout<<"------------------------测试虚析构"<<std::endl;IBase2* p2 = new IDerive2();delete p2;return 0;}
这里写了2个基类,一个是虚析构, 一个不是虚析构。在面向对象的程序中。使用父类指针指向子类对象是很正常。但是对这个指针delete时,使用非虚析构函数就会出现问题。
下面运行代码:

$ ./debug.exe------------------------测试非虚析构执行了 IBase1 的构造函数执行了 IDerive1 的构造函数执行了 IBase1 的析构函数------------------------测试虚析构执行了 IBase2 的构造函数执行了 IDerive2 的构造函数执行了 IDerive2 的析构函数执行了 IBase2 的析构函数

结果很明显,非虚析构的父类指针在delete的时候,并没有执行子类的析构函数。可以想象如果我们子类中有我们动态申请的内存,或者文件资源需要释放,那么这些资源的的释放就会被忽略了。

结论:如果一个类在以后的使用中可能成为基类,就使用virtual析构。

0 0
原创粉丝点击