C++基类的析构函数定义为虚函数的原因
1:每个析构函数只会清理自己的成员(成员函数前没有virtual)。
2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类的析构函数要定义为虚函数;
基类指针可以指向派生类的对象(多态),如果删除该指针delete[]p,就会调用该指针指向的派生类的析构函数,而派生类的对象又会自动调基类的成员函数,这样就会把派生类的对象释放,如果基类的析构函数没有定义成虚函数,则编译器实现的静态绑定,在删除基类的指针,只会释放基类的析构函数而不会释放派生类的成员函数,此时会导致释放内存不完全,就会导致内存泄露的问题。
一:派生类指针指向派生类的对象
class Base
{
public: Base()
{ cout << "Base()" << endl; }
virtual ~Base()
{
cout << "~Base()" << endl;
}
};
class Driver :public Base
{
public: Driver()
{
cout << "Driver()" << endl;
}
~Driver()
{
cout << "~Driver()" << endl;
}
};
void Test()
{
Driver*pd = new Driver;
delete pd;
}
结果:
base()
Driver()
~Driver()
~Base()
派生的指针指向派生类的对象,释放p的过称是先释放派生类的析构函数,再释放基类的析构函数
二:基类的指针指向派生类的对象(无virtual)
class Base
{ public: Base()
{
cout << "Base()" << endl;
}
~Base()
{
cout << "~Base()" << endl;
}
}; class Driver :public Base
{ public: Driver()
{
cout << "Driver()" << endl;
}
~Driver()
{
cout << "~Driver()" << endl;
}
};
void Test()
{
Base *pd = new Driver;
delete pd;
}
运行结果:
Base()
Driver()
~Basce()
当基类的指针指向派生类的对象的成员,释放pd的过程是:只是释放了基类的资源,而没有调用派生类的析构函数;这样的删除只能删除基类对象,而不能删除派生类的对象,造成内存泄露;
在公有继承中,基类对派生类的对象的操作,只能影响哪些继承的成员,如果想要基类对非继承进行操作,则要把这个基类函数定义为虚函数;
C++基类的析构函数定义为虚函数的原因的更多相关文章
- C++中为什么要将析构函数定义成虚函数
构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个 ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...
- C++析构函数定义为虚函数(转载)
转载:http://blog.csdn.net/alane1986/article/details/6902233 析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函 ...
- C++多态性中基类析构函数声明为虚函数
在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...
- 构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数
一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数 ...
- 【C++】C++中基类的析构函数为什么要用virtual虚析构函数?
正面回答: 当基类的析构函数不是虚函数,并且基类指针指向一个派生类对象,然后通过基类指针来删除这个派生类对象时,如果基类的析构函数不是虚析构函数,那么派生类的析构函数就不会被调用,从而产生内存泄漏 # ...
- C++构造与析构函数中调用虚函数的问题
前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...
- C++中基类的析构函数为什么要用virtual虚析构函数
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
随机推荐
- canvas-tangram.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 电脑黑屏,提示信息:windows 无法验证此文件的数字签名。
前言 前几天,在群聊里,有个发小@我,发了张截图,说电脑打不开机了,黑屏,说什么windows 无法验证此文件的数字签名.我当时发了个纠结的表情,意思是我不是专业修电脑的,为什么问我啊.她说怎么了,好 ...
- form的重置reset
HTML中Form表单的reset方法被用来重置用户所输入的内容,以前一直误以为其是单纯的将input等输入项中的值清空. 但实际上不是这样的,reset方法的本质是将input等输入项中的内容还原为 ...
- jenkins无法获取插件的解决办法
很多同学在初次配置Jenkins时,是需要安装一些插件的,但是在可选插件和已安装插件里,全都是空白的. 这是为什么呢? 是因为,Jenkins默认的更新站点服务器在国外,但我们身处天朝,所以这个站点已 ...
- Python 基于python编写一些算法程序等
基于python编写一些算法程序等 by:授客 QQ:1033553122 QQ群:7156436 没特意去研究,只是这对群友在QQ群里(7156436)提出的一些小程序实现.编程题,算法.问题等,本 ...
- 排错-lr回放错误Vuser failed to initialize extensi...解决方法
lr回放错误:Vuser failed to initialize extension LrXml.dll解决方法 by:授客 QQ:1033553122 步骤1:找到LR安装位置,打开协议目录 ...
- Jni OnLoad()和OnUnload()
除了前面说的自定义JNI函数之外,JNI还提供了两个特殊函数,它们是JNI_OnLoad()和JNI_OnUnload(),分别在加载库和卸载库的时候调用. 1.JNI_OnLoad() Java调用 ...
- 网页html随机切换背景图片
首先要准备一些图像,图像的大小(无论是尺寸大小还是数据大小)要控制好,如果太大,会使用户等不及查看全图就跳出了,如果太小,又会影响页面质量. 在script中将这些图像编为一个数组,便于调用.数组的长 ...
- (网页)HTML小技巧的一些小技巧
转自CSDN: 1.怎样定义网页语言(字符集)? 在制作网页过程中,你首先要定义网页语言,以便访问者浏览器自动设置语言,而我们用所见即所得的HTML工具时,都没有注意到这个问题, ...
- eclipse下载教程
Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成开发环境,如C,C++ ...