C++析构函数为什么要为虚函数?
1.为什么基类的析构函数是虚函数?
在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。
下面转自网络:源地址 http://blog.sina.com.cn/s/blog_7c773cc50100y9hz.html
a.第一段代码
#include<iostream>
using namespace std;
class ClxBase{
public:ClxBase() {};~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};class ClxDerived : public ClxBase{
public:ClxDerived() {};~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};int main(){ ClxDerived *p = new ClxDerived;p->DoSomething();delete p;return 0;}
运行结果:
Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
Output from the destructor of class ClxBase!
这段代码中基类的析构函数不是虚函数,在main函数中用继承类的指针去操作继承类的成员,释放指针P的过程是:先释放继承类的资源,再释放基类资源.
b.第二段代码
#include<iostream> using namespace std; class ClxBase{ public:ClxBase() {};~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; };class ClxDerived : public ClxBase{ public:ClxDerived() {};~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };void DoSomething() { cout << "Do something in class ClxDerived!" << endl; } };int main(){ ClxBase *p = new ClxDerived;p->DoSomething();delete p;return 0;}
输出结果:
Do something in class ClxBase!
Output from the destructor of class ClxBase!
这段代码中基类的析构函数同样不是虚函数,不同的是在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:只是释放了基类的资源,而没有调用继承类的析构函数.调用 dosomething()函数执行的也是基类定义的函数.
一般情况下,这样的删除只能够删除基类对象,而不能删除子类对象,形成了删除一半形象,造成内存泄漏.
在公有继承中,基类对派生类及其对象的操作,只能影响到那些从基类继承下来的成员.如果想要用基类对非继承成员进行操作,则要把基类的这个函数定义为虚函数.
析构函数自然也应该如此:如果它想析构子类中的重新定义或新的成员及对象,当然也应该声明为虚的.
c.第三段代码:
#include<iostream> using namespace std; class ClxBase{ public:ClxBase() {};virtual ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; };class ClxDerived : public ClxBase{ public:ClxDerived() {};~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };void DoSomething() { cout << "Do something in class ClxDerived!" << endl; }; };int main(){ ClxBase *p = new ClxDerived;p->DoSomething();delete p;return 0;}
运行结果:
Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
Output from the destructor of class ClxBase!
这段代码中基类的析构函数被定义为虚函数,在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:只是释放了继承类的资源,再调用基类的析构函数.调用dosomething()函数执行的也是继承类定义的函数.
如果不需要基类对派生类及对象进行操作,则不能定义虚函数,因为这样会增加内存开销.当类里面有定义虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间.所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数.
C++析构函数为什么要为虚函数?相关推荐
- 为什么基类的析构函数要声明成虚函数
记得以后基类(父类) 的析构函数最好是声明为 虚函数 即:virtual 开发中遇到了一个比较傻逼的bug,也证明了理论与实际之间的差距. 在基类中没有声明其析构函数为虚函数,导致delete 释放操 ...
- 构造函数不可以声明为虚函数,析构函数可以声明为虚函数
构造函数不能声明为虚函数,而析构函数可以声明为虚函数,在有的情景下析构函数必须声明为虚函数. 不建议在构造函数和析构函数里调用虚函数. 构造函数不能声明为虚函数的原因? 构造一个对象时,必须知道对象 ...
- 构造函数和析构函数能否声明为虚函数?
构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数. 不建议在构造函数和析构函数里面调用虚函数. 构造函数不能声明为虚函数的原因是: 解释一:所谓虚函数就是多态情况下只执行 ...
- 析构函数为什么写成虚函数?
由于类的多态性,基类指针可以指向派生类的对象.如果删除该基类的指针,就会调用该指针指向的派生类的析构函数,而派生类的析构函数又会自动调用基类的析构函数,这样整个派生类的对象被完全释放.· 如果析构函数 ...
- 【C++深度剖析教程33】C++中的构造函数与析构函数是否可以为虚函数
加qq1126137994 微信:liu1126137994 一起学习更多技术!!! 问题一:构造函数与析构函数可以成为虚函数么? 答案: 1.构造函数不可以成为虚函数 因为在构造函数执行结束后,虚函 ...
- C++——析构函数为什么要为虚函数
注:本文内容来源于zhice163博文,感谢作者的整理. 为什么基类的析构函数是虚函数? 在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生. 下面转自网络:源地址 ht ...
- 析构函数可以为纯虚函数吗?纯虚函数可以有函数体吗?纯虚函数需要函数体吗?
先回答标题中中的几个问题: 析构函数可以为纯虚函数吗? yes. 纯虚函数可以有函数体吗? yes. 纯虚函数需要函数体吗? 一般来讲,如果析构函数是纯虚函数,那么析构函数必须要有函数体,如果是其它函 ...
- 构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?
1.构造函数不能声明为虚函数 1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的.而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等 ...
- C++经验(四)-- 基类构造函数和析构函数中调用virtual虚函数?
class Base {public:Base();virtual void oneFunction() = 0;... };Base::Base() {...oneFunction(); }clas ...
最新文章
- Puppet学习之文件管理
- layui弹出层html,layui-弹出层
- React之setState使用
- ANSI C:+++
- 【Demo 0003】Java基础-数组
- CDays–5 习题二(利用Python科学计算特性,使用常用计算符)及相关内容解析。...
- 【前端后端运维】Web开发人员学习路线,汇总整理
- python新手图解_Python完全新手教程
- ExtAspNet v3.1.9
- HTML行内元素 块级元素及语义化
- 早上内部资源共享讨论发言稿
- 从最理想的情况论证自己的观点,必然错误,为什么明知故犯?
- 【数据预测】基于matlab灰狼算法优化LSSVM数据预测【含Matlab源码 433期】
- 组装多媒体计算机需要什么硬件,多媒体计算机组装与维护教程 第1章 多媒体计算机硬件选购和配置...
- E680最强综合技巧集合
- win软件 精品推荐磁力资源搜索助手 22.01.22中文特别版
- 程序员是学历与能力,哪个重要呢?本文告诉你!
- 18.缓存预热、缓存雪崩、缓存击穿、缓存穿透、性能指标监控等企业级解决方案
- TexturePacker的免费key获取方式
- 1G2G3G4G5G:一部波澜壮阔的移动通信史
热门文章
- Linux风雨20年回顾 道路是沧桑
- 网管日志-06.08.16
- 剑指 Offer II 044. 二叉树每层的最大值
- c语言min函数_C语言探索之旅 | 第一部分第十课:第一个C语言小游戏
- java中输出5个数_编写一个程序,要求用户输入5个数字,并输出这些数字中最大的数字和这些数字中最小的数字...
- 印花导带容易出现的问题及其解决方法
- java线程集合点_Java多线程学习笔记(三) 甚欢篇
- Mongodb2.6升级到Mongodb3.0.2笔记
- 唯有创新不可辜负!混合集成成就云时代创新
- Django 找不到模版报错 django.template.exceptions.TemplateDoesNotExist: index.html