首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于基类构造函数调用虚函数的有关问题

2012-02-26 
关于基类构造函数调用虚函数的问题基类:class Base{Base(){ A()}virtual void A(){coutBase Aendl

关于基类构造函数调用虚函数的问题
基类:
class Base{
  Base(){ A();}
  virtual void A(){cout<<"Base A"<<endl;};
}
派生类:
class Derived:public Base{
  Derived(){}
  void A(){cout<<"Derived A"<<endl;}
}

Base* pb=new Derived();
问现在调用的是基类中的A()还是派生类中的A()? 即打印Base A还是Derived A?

[解决办法]
Base(){ A();}//调用的是Base类中的,很简单,在这个构造函数里面只有基类部分构造好了。另外effective C++里面应该有说过,永远不要在构造函数里面调用虚函数。

[解决办法]
打印Base类中的A,因为在子类构造的时候首先构造父类的对象,不要再构造函数中调用虚函数
[解决办法]
是这样的

编译器在背后给你做了很多事情

Base* pb=new Derived();
后准备进入Derived的构造函数
这个时候编译器发现Derived有基类 并且有默认构造函数 所以在进入derived构造函数之前先进入Base的构造函数

在进入 Base的构造函数 的左大括号后

编译器首先 构造虚函数表 和 vptr
这个时候编译器在base里面操作 虚函数表里的地址都是base类 虚函数的入口地址

当虚函数表和vptr构造好后 继续执行程序员写在base构造函数里面的代码 一直到右括号 退出base构造函数 回到derived构造函数

同理
进入左大括号后
编译器发现vptr和 虚函数表已经建好
这个时候他做的就是 跟新虚函数表里面的地址 用 derived里面重写的虚函数的地址 刷新 原来的地址
做完后 继续执行 程序员写在derived构造函数里面 余下的代码

所以为什么base构造函数里面调用虚函数会是base 自己的了
这些都是因为编译器做了很多事没告诉你

[解决办法]
打印结果是
Base A
Derived A

Base* pb=new Derived(); // 调用基类的构造函数
前提是基类的构造函数是public的

热点排行