先看一个例子:

#include <iostream>
using namespace std;class A{
public:A() {show();}virtual void show(){cout<<"in A"<<endl;}virtual ~A(){show();}
};class B:public A{
public:B() {show();}void show(){cout<<"in B"<<endl;}
};int main(){A *a = new A;delete a;cout << "*****************" << endl;A *b = new B;delete b;
}

输出结果,可以看到没有预想的多态效果:

in A
in A
*****************
in A
in B
in A

结论:构造函数和析构函数调用虚函数时都不使用动态联编,如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本。

原因分析:

(1)不要在构造函数中调用虚函数的原因:因为父类对象会在子类之前进行构造,此时子类部分的数据成员还未初始化, 因此调用子类的虚函数是不安全的,故而C++不会进行动态联编。
(2)不要在析构函数中调用虚函数的原因:析构函数是用来销毁一个对象的,在销毁一个对象时,先调用子类的析构函数,然后再调用基类的析构函数。所以在调用基类的析构函数时,派生类对象的数据成员已经“销毁”,这个时再调用子类的虚函数已经没有意义了。

转载于:https://www.cnblogs.com/bonelee/p/5826196.html

C++构造函数和析构函数调用虚函数时都不会使用动态联编相关推荐

  1. C++构造函数与析构函数调用虚函数的注意事项

    虽然可以对虚函数进行实调用,但程序员编写虚函数的本意应该是实现动态联编.在构造函数中调用虚函数,函数的入口地址是在编译时静态确定的,并未实现虚调用.但是为什么在构造函数中调用虚函数,实际上没有发生动态 ...

  2. 构造函数调用虚函数的问题

    一般情况下,不允许在构造函数或者析构函数中调用虚函数.其实语法上都没有问题,只是会失去多态性. 如果在构造函数中调用虚函数,会先调用父类中的实现,也就失去了多态的性质. class A {public ...

  3. 虚拟函数-1、静态联编与动态联编,引入虚函数

    在实际开发工作中,为提高代码的重用性,编写通用的功能模块,往往需要设计处理几种不同对象的通用程序,如示例2.1所示. 示例清单2.1 #include "stdio.h" #inc ...

  4. 构造函数为什么不能是虚函数 ( 转载自C/C++程序员之家)

    从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用, ...

  5. 构造函数为什么不能是虚函数

    从存储空间角度看 虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的. 问题出来了,假设构造函数是虚的.就须要通过 vtable来 ...

  6. 为什么构造函数不能声明为虚函数,析构函数可以,构造函数中为什么不能调用虚函数?

    为什么构造函数不能声明为虚函数,析构函数可以,构造函数中为什么不能调用虚函数 构造函数中为什么不能调用虚函数? 第一个理由是概念上的 第二个理由是机械上的. 构造函数不能声明为虚函数的原因是 1 构造 ...

  7. 构造函数不可以是虚函数;析构函数可以是虚函数,也可以是纯虚函数。

    构造函数不可以是虚函数:析构函数可以是虚函数,也可以是纯虚函数. 一:构造函数不能声明为虚函数的原因 1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的. 而在构造 ...

  8. C++ 类继承:构造函数与析构函数调用顺序,派生类和基类之间的特殊关系,公有继承及其他

    文章目录 一.派生类构造函数与基类构造函数 二.创建与销毁派生类对象时,构造函数和析构函数的调用 三.派生类和基类之间的特殊关系 四.公有继承 (一).何为公有继承 (二).多态公有继承 (三).虚函 ...

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

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

最新文章

  1. nginx 404 403等错误信息页面重定向到网站首页或其它事先指定的页面
  2. python namedtuple用法_Python namedtuple(命名元组)使用实例
  3. [C++] Variable storage space
  4. 10.2 梯度下降-机器学习笔记-斯坦福吴恩达教授
  5. 准时制 jit 减少库存
  6. Postgresql 查看当前数据库所有的触发器
  7. 调用别人服务器运行本地文件方法
  8. 伯克利人工智能导论课开放:视频、PPT和练习都在这 | 资源
  9. mysql的联表删除
  10. mysql update 几万 非常慢_MySQL慢日志这样分析才够味
  11. 北理工c语言作业 2048,C语言实现2048小游戏
  12. DDR和LPDDR、LPDDR4和LPDDR4X的区别 LPDDR5
  13. 在ajax中幸运抽奖,JS实现幸运抽奖页面
  14. web攻击之一:XSS跨站脚本
  15. 还记的 破坏之王 里面的 锁吗,锁住 断水流大师兄
  16. 数字图像处理-高反差保留算法
  17. 常见噪声及其消除的方式
  18. MTK平台Metadata的加载(3)——其他Static和Request加载
  19. 梯有N阶,上楼可以一步上一阶,也可以一次上二阶(Java实现)
  20. 3dmax导出glb格式_教你如何用ArcGIS 和 3DMax 建模,长知识

热门文章

  1. 大数据SQL日常学习——NVL函数
  2. jdbcutils.java_空指针异常错误哪个地方错了Exception in thread main (JdbcUtils.java:62) main(JdbcUtils.java:87)...
  3. mysql怎么实现确认收货_Tp结合redis实现订单自动收货
  4. java需要前台封装对象吗_javaEE之-----------类反射直接封装前台传过来的参数
  5. python基本图形绘制_【Python】Python基本图形绘制-Go语言中文社区
  6. 宿松长铺程集高中2021年高考成绩查询,2017宿松程集中学录取分数线(附2017高考成绩喜报)...
  7. 电子自动窗帘系统c语言程序,单片机自动窗帘控制程序(两个电机)
  8. h2 迁移到 mysql_[saiku] 将saiku自带的H2嵌入式数据库迁移到本地mysql数据库
  9. 手机号和邮箱正则匹配
  10. 你花了多久弄明白架构设计?java多线程编程实战指南pdf