C++C++C++:构造函数和析构函数能否为虚函数?

简单回答是:构造函数不能为虚函数,而析构函数可以且常常是虚函数。

1.构造函数不能为虚函数

让我们来看看大牛C++C++C++之父 BjarneBjarneBjarne StroustrupStroustrupStroustrup 在《TheTheThe C++C++C++ ProgrammingProgrammingProgramming LanguageLanguageLanguage》里是怎么说的:

ToToTo constructconstructconstruct ananan objectobjectobject, aaa constructorconstructorconstructor needsneedsneeds thethethe exactexactexact typetypetype ofofof thethethe objectobjectobject ititit isisis tototo createcreatecreate. ConsequentlyConsequentlyConsequently, aaa constructorconstructorconstructor cannotcannotcannot bebebe virtualvirtualvirtual. FurthermoreFurthermoreFurthermore, aaa constructorconstructorconstructor isisis notnotnot quitequitequite ananan ordinaryordinaryordinary functionfunctionfunction, InInIn particularparticularparticular, ititit interactsinteractsinteracts withwithwith memorymemorymemory managementmanagementmanagement ininin wayswaysways ordinaryordinaryordinary membermembermember functionsfunctionsfunctions don′tdon'tdon′t. ConsequentlyConsequentlyConsequently, youyouyou cannotcannotcannot havehavehave aaa ponterponterponter tototo aaa constructor.constructor.constructor.

— FromFromFrom 《TheTheThe C++C++C++ ProgammingProgammingProgamming LanguageLanguageLanguage》15.6.215.6.215.6.2

翻译:普通函数要构造一个对象,构造函数需要它要创建的对象的确切类型。因此,构造函数不能是虚函数。此外,构造函数并不是一个很普通的函数,特别是它与内存管理的交互方式与普通成员函数不同,因此,你不能拥有一个构造函数的桥接器。

然而大牛就是大牛,这段话对一般人来说太难理解了。那下面就试着解释一下为什么:

这就要涉及到C++C++C++对象的构造问题了,C++C++C++对象在三个地方构建:

  • 函数堆栈
  • 自由存储区,或称之为堆
  • 静态存储区

无论在那里构建,其过程都是两步:首先,分配一块内存;其次,调用构造函数。好,问题来了,如果构造函数是虚函数,那么就需要通过vtablevtablevtable 来调用,但此时面对一块 rawrawraw memeorymemeorymemeory(原始内存),到哪里去找 vtablevtablevtable 呢?毕竟,vtablevtablevtable 是在构造函数中才初始化的啊,而不是在其之前。因此构造函数不能为虚函数。

2.析构函数可以是虚函数,且常常如此

这个就好理解了,因为此时 vtablevtablevtable 已经初始化了;况且我们通常通过基类的指针来销毁对象,如果析构函数不为虚的话,就不能正确识别对象类型,从而不能正确销毁对象。

困惑我们的是我们却经常看到“虚构造函数”这样的说法,这就要归咎于不负责任或者说误人子弟的媒体了(包括书、技术文章等等)。因为他们说的是类似下面这样的做法:

class Expr {public:Expr();Expr(const Expr&);virtual Expr* new_expr() { return new Expr(); }virtual Expr* clone() { return new Expr(*this); }
};

参考:C++:构造函数和析构函数能否为虚函数
更多解读:
为什么C++的构造函数不可以是虚函数,而析构函数可以是虚函数

构造函数与析构函数能否为虚函数?相关推荐

  1. C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配

    一.构造函数和析构函数中对虚函数的调用 仍然以https://blog.csdn.net/Master_Cui/article/details/109957302中的代码为例 base3构造函数和析构 ...

  2. C++:构造函数和析构函数能否为虚函数

    C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可以且常常是虚函数. (1) 构造函数不能为虚函数 让我们来看看大牛C++之父 Bjarne Stroustrup ...

  3. (c++)5.4构造函数和析构函数中调用虚函数

    在构造函数和析构函数中调用虚函数时,采用静态联编(他们所调用的虚函数是自己类中定义的函数) 如果在自己类中没有实现这个虚函数,则调用的是基类中的虚函数,绝不会是任何在派生类中重定义的虚函数 //构造函 ...

  4. C++核心准则C.82:不要在构造函数或析构函数中调用虚函数

    C.82: Don't call virtual functions in constructors and destructors C.82:不要在构造函数或析构函数中调用虚函数 Reason(原因 ...

  5. C++中最好不要在构造函数和析构函数中调用虚函数!!!

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  6. C/Cpp / C++ 构造函数和析构函数可以是虚函数吗

    答案 构造函数不可以是虚函数,而析构函数可以且常常是虚函数. 原因 1.构造函数不可以是虚函数 当类中声明虚函数时,编译器会在类中生成一个虚函数表,虚函数表是一个存储成员函数指针的数据结构. 虚函数表 ...

  7. C++中最好不要在构造函数和析构函数中调用虚函数

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  8. C++学习笔记-----不要在构造函数和析构函数中调用虚函数

    考虑下面的程序: #include <iostream> using namespace std;class Base { public:Base() { cout << &q ...

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

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

最新文章

  1. centos 扫毒软件clamAV安装
  2. 数字图像处理4:图像的像素级运算
  3. java 算法--洗牌算法
  4. 2018年看好这些半导体企业
  5. mysql视图_mysql之视图详解
  6. [Java] 关键字final、static使用总结
  7. VC的MFC中重绘函数的使用总结(整理)
  8. PyTorch的13个必知必会知识点
  9. Python 练习册,每天一个小程序
  10. 认识Windows Communication Foundation
  11. 【包邮送书活动】20210924期-开奖通知
  12. java 变量作用域 c语言_C语言深入理解 - 常量与变量
  13. 新天龙官网服务器更新消息,新天龙八部怀旧服太火,增开7组服务器不够用,还得继续扩容...
  14. 在自动驾驶技术上,一向自信满满的马斯克也承认了特斯拉的不足
  15. 热敏电阻温度采集简述
  16. 什么叫做石英表_什么是石英表?石英表与机械表的区别
  17. Oracle 12c数据库坏块检查
  18. java山地车 故障,十年骑龄车友总结山地车保养维修技巧
  19. C语言数据的表现形式及其运算
  20. 多个中通快递的物流情况是怎么批量查询并保存的

热门文章

  1. 剪辑副业怎么接单?学完剪辑去哪里可以接单赚钱
  2. Prawn:使用Ruby生成PDF更简捷
  3. 学习笔记:SpringCloud 微服务技术栈_实用篇①_基础知识
  4. vue router 报错: Uncaught (in promise) NavigationDuplicated {_name:““NavigationDuplicated“... 的解决方法
  5. 统计各部门的薪水总和_你必须知道的SAP中统计指标设置和应用
  6. Android教程(十二)-- 使用DisplayMetrics获取手机分辨率
  7. 写了个魔兽争霸辅助工具
  8. 自考java填空题_java 自考题目
  9. 乔布斯与盖茨罕见合影:一生之敌 并肩而行
  10. ❓[杂谈小记]lean‘s LEDE or OPENWRT