先看一个例子:

#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)不要在析构函数中调用虚函数的原因:析构函数是用来销毁一个对象的,在销毁一个对象时,先调用子类的析构函数,然后再调用基类的析构函数。所以在调用基类的析构函数时,派生类对象的数据成员已经“销毁”,这个时再调用子类的虚函数已经没有意义了。

C++构造函数和析构函数调用虚函数时都不会使用动态联编的更多相关文章

  1. C++ 构造函数或析构函数调用虚函数

    构造函数和析构函数中的虚函数 在执行基类构造函数时,对象的派生类部分是未初始化的.实际上,此时对象还不是一个派生类对象. 为 了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化.在基类 ...

  2. C++ 构造函数、析构函数与虚函数的关系

    编译环境:windows 10 + VS2105 1.构造函数不能为虚函数 虚函数的作用是为了实现C++多态机制.基类定义虚函数,子类可以重写该虚函数.当子类重写父类虚函数后,父类指针指向子类地址时, ...

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

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

  4. 构造函数为什么不能为虚函数 &amp; 基类的析构函数为什么要为虚函数

    一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数 ...

  5. 转 C++构造函数、析构函数、虚函数之间的关系

    C++构造函数.析构函数.虚函数之间的关系 1. 如果我们定义了一个构造函数,编译器就不会再为我们生成默认构造函数了.2. 编译器生成的析构函数是非虚的,除非是一个子类,其父类有个虚析构,此时的函数虚 ...

  6. C++单继承的构造函数和析构函数调用的顺序

    1.继承构造函数调用顺序以及销毁的过程 先调用父类的构造函数,在调用子类的构造函数,析构函数调用相反.

  7. C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编

    函数重写:(在子类中重写父类中的函数) 父类中被重写的函数  依然会继承  给子类. 子类中重写的函数将覆盖父类中的函数. 通过作用域分辨符  ::  可以访问到父类中的函数. 例如: #includ ...

  8. 12.C++-构造函数与析构函数调用顺序,const成员函数,const对象

    单个对象创建时,构造函数的调用顺序 1.首先判断该对象的类是否拥有父类,若有则先调用父类的构造函数 2.判断该对象的成员是否是其它类的成员,若是则调用成员变量的构造函数(调用顺序和声明顺序相同) 3. ...

  9. C++构造函数中不能调用虚函数

    在构造函数中调用虚函数,并不会产生多态的效果,就跟普通函数一样. c++ primer 第四版中497页15.4.5构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...

随机推荐

  1. Python入门-行和缩进

    学习Python与其他语言最大的区别就是,Python的代码块不使用大括号({})来控制类,函数以及其他逻辑判断.python最具特色的就是用缩进来写模块. 缩进的空白数量是可变的,但是所有代码块语句 ...

  2. HDU 5826 physics(物理)

     physics(物理) Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   D ...

  3. Base64加密解密原理以及代码实现(VC++)

    Base64加密解密原理以及代码实现 转自:http://blog.csdn.net/jacky_dai/article/details/4698461 1. Base64使用A--Z,a--z,0- ...

  4. 预习 jQuary

    一.jQuary简介 1.jQuery 库 - 特性 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML 元素选取 HTML 元素操作 CSS 操作 HTM ...

  5. js操作cookie,实现登录密码保存 [转]

    转自:http://blog.csdn.net/zyujie/article/details/8727828 ( 谢谢博主了) js操作cookie,实现登录密码保存.cookie的存放方式是以键值对 ...

  6. shell script数组使用函数输出

    #!/bin/bash # array variable to function test function testit { local newarray newarray=("$@&qu ...

  7. server-pc--------------->lspci,lsusb,meminfo等配置信息

    安装yum install pciutils usbutils [root@server09 ~]# [root@server09 ~]# lspci00:00.0 Host bridge: Inte ...

  8. poj2546Circular Area(两圆相交面积)

    链接 画图推公式 这两种情况 都可用一种公式算出来 就是两圆都求出圆心角 求出扇形的面积减掉三角形面积 #include <iostream> using namespace std; # ...

  9. ERROR 1201 (HY000) Could not initialize master info structure

    1.错误原因:Slave线程启动出现问题.2.解决办法一:stop slave; reset slave; start slave; show slave status\G3.如果解决方法一,还是失败 ...

  10. python模块以及导入出现ImportError: No module named 'xxx'问题

    python中,每个py文件被称之为模块,每个具有__init__.py文件的目录被称为包.只要模块或者包所在的目录在sys.path中,就可以使用import 模块或import 包来使用如果你要使 ...