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++析构函数为什么要为虚函数?相关推荐

  1. 为什么基类的析构函数要声明成虚函数

    记得以后基类(父类) 的析构函数最好是声明为 虚函数 即:virtual 开发中遇到了一个比较傻逼的bug,也证明了理论与实际之间的差距. 在基类中没有声明其析构函数为虚函数,导致delete 释放操 ...

  2. 构造函数不可以声明为虚函数,析构函数可以声明为虚函数

    构造函数不能声明为虚函数,而析构函数可以声明为虚函数,在有的情景下析构函数必须声明为虚函数.  不建议在构造函数和析构函数里调用虚函数. 构造函数不能声明为虚函数的原因? 构造一个对象时,必须知道对象 ...

  3. 构造函数和析构函数能否声明为虚函数?

    构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数. 不建议在构造函数和析构函数里面调用虚函数. 构造函数不能声明为虚函数的原因是: 解释一:所谓虚函数就是多态情况下只执行 ...

  4. 析构函数为什么写成虚函数?

    由于类的多态性,基类指针可以指向派生类的对象.如果删除该基类的指针,就会调用该指针指向的派生类的析构函数,而派生类的析构函数又会自动调用基类的析构函数,这样整个派生类的对象被完全释放.· 如果析构函数 ...

  5. 【C++深度剖析教程33】C++中的构造函数与析构函数是否可以为虚函数

    加qq1126137994 微信:liu1126137994 一起学习更多技术!!! 问题一:构造函数与析构函数可以成为虚函数么? 答案: 1.构造函数不可以成为虚函数 因为在构造函数执行结束后,虚函 ...

  6. C++——析构函数为什么要为虚函数

    注:本文内容来源于zhice163博文,感谢作者的整理. 为什么基类的析构函数是虚函数? 在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生. 下面转自网络:源地址 ht ...

  7. 析构函数可以为纯虚函数吗?纯虚函数可以有函数体吗?纯虚函数需要函数体吗?

    先回答标题中中的几个问题: 析构函数可以为纯虚函数吗? yes. 纯虚函数可以有函数体吗? yes. 纯虚函数需要函数体吗? 一般来讲,如果析构函数是纯虚函数,那么析构函数必须要有函数体,如果是其它函 ...

  8. 构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?

    1.构造函数不能声明为虚函数 1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的.而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等 ...

  9. C++经验(四)-- 基类构造函数和析构函数中调用virtual虚函数?

    class Base {public:Base();virtual void oneFunction() = 0;... };Base::Base() {...oneFunction(); }clas ...

最新文章

  1. Puppet学习之文件管理
  2. layui弹出层html,layui-弹出层
  3. React之setState使用
  4. ANSI C:+++
  5. 【Demo 0003】Java基础-数组
  6. CDays–5 习题二(利用Python科学计算特性,使用常用计算符)及相关内容解析。...
  7. 【前端后端运维】Web开发人员学习路线,汇总整理
  8. python新手图解_Python完全新手教程
  9. ExtAspNet v3.1.9
  10. HTML行内元素 块级元素及语义化
  11. 早上内部资源共享讨论发言稿
  12. 从最理想的情况论证自己的观点,必然错误,为什么明知故犯?
  13. 【数据预测】基于matlab灰狼算法优化LSSVM数据预测【含Matlab源码 433期】
  14. 组装多媒体计算机需要什么硬件,多媒体计算机组装与维护教程 第1章 多媒体计算机硬件选购和配置...
  15. E680最强综合技巧集合
  16. win软件 精品推荐磁力资源搜索助手 22.01.22中文特别版
  17. 程序员是学历与能力,哪个重要呢?本文告诉你!
  18. 18.缓存预热、缓存雪崩、缓存击穿、缓存穿透、性能指标监控等企业级解决方案
  19. TexturePacker的免费key获取方式
  20. 1G2G3G4G5G:一部波澜壮阔的移动通信史

热门文章

  1. Linux风雨20年回顾 道路是沧桑
  2. 网管日志-06.08.16
  3. 剑指 Offer II 044. 二叉树每层的最大值
  4. c语言min函数_C语言探索之旅 | 第一部分第十课:第一个C语言小游戏
  5. java中输出5个数_编写一个程序,要求用户输入5个数字,并输出这些数字中最大的数字和这些数字中最小的数字...
  6. 印花导带容易出现的问题及其解决方法
  7. java线程集合点_Java多线程学习笔记(三) 甚欢篇
  8. Mongodb2.6升级到Mongodb3.0.2笔记
  9. 唯有创新不可辜负!混合集成成就云时代创新
  10. Django 找不到模版报错 django.template.exceptions.TemplateDoesNotExist: index.html