(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++算法原理与实践-董飞-课程笔记(一)

GeekBand-极客班-C++算法原理与实践-董飞-课程笔记(一)算法入门和编程风格

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

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

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

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

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

引言        为什么今天要讨论继承、复合当中的构造和析构?对于C++来说,类的构造函数和析构函数的主体通常是只负责自身的构造和析构,而继承和复合之后,往往会调用父类和复合类的构造函数和析构函数,...

Effective C++笔记09:绝不在构造函数和析构过程中调用virtual 函数

Effective C++ 条款9梳理

Effective c++学习笔记——条款09:绝不在构造和析构过程中调用virtual函数

Never call virtual functions during construction or destruction     这是本条款的核心,不该在构造函数和析构函数期间调用virtua...

Effective c++学习笔记——条款09:绝不在构造和析构过程中调用virtual函数

Never call virtual functions during construction or destruction     这是本条款的核心,不该在构造函数和析构函数期间调用virtua...

C++构造与析构(16) - virtual构造函数

C++能否定义构造函数为virtual来创建多态的对象? 答案是不行!C++是一门静态类型的语言(RTTI的目的与这里的动态创建对象不同),多态地创建对象没有什么意义。编译器必须知道类的确切类型,才能...

《Effective C++》item9:决不在构造和析构过程中调用virtual函数

这是一个很容易让人迷惑的principle!按照我们对C++多态性的理解:定义基类中某个函数为虚函数是为了允许用基类的指针来调用子类的这个函数。通过virtual函数实现程序运行时候的动态调用。   ...

C++构造与析构(17) - virtual拷贝构造函数

在上一篇的中介绍了实现"virtual constructor"的方法。点击此链接。 有没有可能在不知道类的类型的情形下创建一个对象? 众所周知,拷贝构造函数是用一个已经存在的对象,来构造一个新的对象...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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