关闭

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

146人阅读 评论(0) 收藏 举报
分类:

在这次作业点评中发现很多同学都没有在基类的析构函数使用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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1343次
    • 积分:73
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章分类
    文章存档
    最新评论