构造函数不能声明为虚函数,而析构函数可以声明为虚函数,在有的情景下析构函数必须声明为虚函数。 
不建议在构造函数和析构函数里调用虚函数。

构造函数不能声明为虚函数的原因?

构造一个对象时,必须知道对象实际类型,而虚函数是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功,编译器就无法知道对象的实际类型,是该类本身,还是派生类,还是其他。

虚函数的执行依赖于虚函数表,而虚函数表是在构造函数中进行初始化的,即初始化虚表指针(vptr),使得正确指向虚函数表。而在构造对象期间,虚函数表(vtable)还没有被初始化,将无法进行。

析构函数设为虚函数的原因?

当基类指针指向子类对象的时候,当调用基类的析构函数释放内存时,由于析构函数不具有多态性,因此只会执行基类的析构函数,子类内存无法释放,因此造成内存泄漏。

当将基类的析构函数设定为虚函数的话,当调用基类的析构函数释放内存时,会先去执行子类的析构函数释放子类的内存,之后再调用基类的析构函数,释放基类的内存。

析构函数的作用在对象撤销前把类的对象从内存中撤掉,通常系统只会执行基类的析构函数,不执行派生类的析构函数。

将基类的析构函数声明为虚函数,当撤销基类对象的同时也撤销派生类的对象,这个过程是动态关联完成的。

析构函数设为虚函数的原因是为了防止内存泄露。在继承体系中,当基类的指针或引用指向派生类,用基类delete时,如果析构函数没有声明为虚函数,只能析构基类对象,派生类对象将无法析构。

建议将析构函数设为虚函数。

当想使用子类的指针直接释放子类的对象时,会先执行子类的析构函数,再执行基类的析构函数,再执行基类的基类的析构函数,以此类推!

说明:
使用虚函数,系统会有一定的空间开销。当一个类带有虚函数时,编译系统会为该类构造一个虚函数表,是一个指针数组,存放每个虚函数的入口地址。系统在进行动态关联的时间开销很少,提高了多态性的效率。
编译器生成的析构函数都是非虚的,除非是一个子类,其父类有个虚析构函数,此时的虚函数特性继承自基类。
有虚函数的类,一般情况下要定义一个虚析构函数。

纯虚函数
在有的情景下,基类的虚函数是为了派生类中的使用而声明定义的,但在基类中没有任何意义,此类函数称为纯虚函数,不需要写成空函数的形式,只需要在声明为以下格式:

virtual 函数类型 函数名(形参列表) = 0;
1
纯虚函数是没有函数体的,“=0”并不代表函数的名字不具备函数的功能,不能被调用,在派生类中对该函数定义后,才能具备函数的功能,可以被调用。

构造函数不可以声明为虚函数,析构函数可以声明为虚函数相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

  7. 静态联编,动态联编,类指针之间的关系,虚函数与多态性,纯虚函数,虚析构函数

    1.静态联编,是程序的匹配,连接在编译阶段实现,也称为早期匹配.重载函数使用静态联编. 2.动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编.switch语句和if语句是动态联编的例子. #i ...

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

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

  9. C++析构函数为什么要为虚函数?

    1.为什么基类的析构函数是虚函数? 在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生. 下面转自网络:源地址 http://blog.sina.com.cn/s/blo ...

最新文章

  1. Jquery前端分页插件pagination同步加载和异步加载
  2. 数梦工场联手阿里云 推出大数据一体机
  3. java修改动态视频,直播视频app源码,动态修改cron
  4. 从零入门 Serverless | Serverless 应用如何管理日志 持久化数据
  5. linux 开机启动文件夹,Linux开机启动流程
  6. 约翰霍姆金斯大学_the I-STAR Lab
  7. SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
  8. mybatis传参数
  9. android 对称加密和非对称加密,Android开发加密之对称与非对称加密算法使用案例.pdf...
  10. 2013-11-11 Oracle 课堂测试 练习题 例:BULK COLLECT及return table
  11. 找不到libmmd.dll无法继续执行代码_代码中的软件工程 - xieyupei
  12. 连接定义点作用_【干货】我的期货交易入场点分析
  13. 电脑硬件知识大扫盲:主板知识大全
  14. JAVA 如何将String进行大小写转换
  15. 计算机入门认识图标,初学UI设计如何了解ICON图标的用处
  16. 初中计算机教案ps,初中信息技术《认识Photoshop CS2的工作界面》教案
  17. C#中COM串口连接、发送、接收数据
  18. 稳压二极管的原理,它有什么作用?
  19. 如何快速学习:掌握任何技能的 10 种行之有效的方法
  20. 感性认识spring的IoC

热门文章

  1. C# Combobox联动
  2. js 算法排序总结
  3. mini CentOS7 安装 mysql
  4. 【中文】Joomla1.7扩展介绍之JoomSEF Free (搜索引擎友好)
  5. 【C/C++】 读、写二进制文件经典实例
  6. libevent之Reactor模式详解
  7. java与 C++ 之间进行 SOCKET 通讯要点简要解析
  8. mysql分库分表风险_数据库分库分表存在的问题及解决方案
  9. python sftp_Python使用sftp实现上传和下载功能(实例代码)
  10. java空值转datetime,关于java1.8中LocalDateTime实现日期,字符串互转小坑。