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

原创 2016年05月30日 16:57:25

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

极客班GeekBand - C++面向对象高级开发 - 2

极客班GeekBand - C++面向对象高级开发 - 2极客班GeekBand - C面向对象高级开发 - 2 讲师 - 侯捷 复习Complex类的实现过程 三大函数拷贝构造拷贝复制析构 栈堆与内...
  • lionpku
  • lionpku
  • 2015年07月28日 16:12
  • 1109

(GeekBand或极客班) inline 函数的思考。(第二季)

在第一季中,我简单的写了一个实验。来证明了inline函数的执行效率。 随后 Richard_HuTianyi 在评论中提出了一些自己的见解。其中我对inline函数无法inline的情况产生了疑...

极客班GeekBand C++第一周笔记

极客班GeekBand C++第一周笔记 防卫式声明 #ifndef _xxx_ #define _xxx_ (程序段) #endif 作用:不使用防卫式声明会反复include引入...

析构函数,必须是virtual的,否则会内存泄漏

AMF0String => AMF0Base 假设析构函数不是virtual: AMF0String* s = new AMF0String("abc"); delete s; //没有问题,可以...

(GeekBand或极客班)简单对象构造过程分析。

在继承和组合中,对象的构造顺序一般是由编译器默认处理,我们在写代码的时候非常容易忽略,为了记录和验证本课中对象的构造和析构顺序,现在讲我的过程记录下来。 1--单一继承的情况: #incl...

极客班GeekBand - C++第一次课程辅导 - 李建忠

极客班GeekBand - C++第一次课程辅导 - 李建忠极客班GeekBand - C第一次课程辅导 - 李建忠 栈Stack VS 堆heap 堆对象的空间分析 栈对象的空间分析 变量模型与使用...
  • lionpku
  • lionpku
  • 2015年07月25日 19:27
  • 1852

GeekBand-极客班-C++算法原理与实践-董飞-课程笔记(一)

GeekBand-极客班-C++算法原理与实践-董飞-课程笔记(一)算法入门和编程风格
  • lionpku
  • lionpku
  • 2015年07月20日 16:23
  • 1208

Geekband作业12--寻找内存泄漏

bug项目地址:https://github.com/lzyzsd/MemoryBugs 所用到的工具:AS1.5+, Memory monitor, Allocation tracker, Hea...

Virtual Leak Detector 工具的使用 --- VC开发内存泄漏检测工具

Virtual Leak Detector 使用方法   Virtual Leak Detector,内存泄漏检测工具,开源,易用。仅支持VC平台,如VS系列,VC6.0。   使用方法 1...
  • wwww4
  • wwww4
  • 2015年12月18日 15:08
  • 2091

GeekBand C++学习笔记——继承、复合当中的构造与析构

引言        为什么今天要讨论继承、复合当中的构造和析构?对于C++来说,类的构造函数和析构函数的主体通常是只负责自身的构造和析构,而继承和复合之后,往往会调用父类和复合类的构造函数和析构函数,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:(GeekBand或极客班) 你的内存泄漏了--- 之 virtual 析构
举报原因:
原因补充:

(最多只允许输入30个字)