绝不在构造/析构函数中使用虚函数

假设有一个class继承体系,在构造函数中调用了一个虚函数,如:
  1. class A{
  2. public:
  3. A();
  4. virtual void dosomething();
  5. }
  6. A::A()
  7. {
  8. dosomething();
  9. }
  1. class B:public A{
  2. public:
  3. virtual void dosomething();
  4. }
然后执行如下语句
  1. B b;
无疑的,会有B的构造函数被调用,但首先A的构造函数会被调用,因为基类的构造函数总是先于派生类的构造函数被调用。
而此时在A的构造函数中被调用的dosomething()函数是A的版本,而不是被B覆盖的版本。因为在A的构造期间,b还是个基类对象,
不可能访问到B覆盖的版本,否则会导致不明确行为。比如B的dosomething()可能访问了某个派生成员,而在A的构造期间,那些派生成员
都还没被构造出来,这样就会导致不明确行为。

相同道理也适用于析构函数,一旦派生类析构函数开始执行,对象内的派生类成员变量就呈现为定义值,C++视他们不存在,进入基类虚构函数后对象就变成一个基类对象。

解决的办法是将那个函数声明为非虚的但需要参数。
由于你无法使用虚函数从基类向下调用,在构造期间,可以由派生类将必要的构造信息向上传递至基类构造函数加以弥补。




posted @ 2016-11-19 15:14  Lighters_c  阅读(150)  评论(0)    收藏  举报