在施工和销毁期间调用虚拟方法

时间:2012-11-19 18:33:23

标签: c++ inheritance virtual-functions

在构造和销毁期间调用虚方法会导致编译器错误?我听说做这件事很危险。

我知道如果我有Class Base定义虚拟方法foo()foo()的分辨率在{{1}的所有子类中都是动态 }}。因此,如果子类Base覆盖Derived,则调用foo()。那么为什么在构造/销毁期间调用虚拟方法会让编译器感到困惑呢?

从构造函数和它之外调用它们有什么区别?

2 个答案:

答案 0 :(得分:5)

在构造Base()期间,派生类尚未初始化,并且尚未真正存在。当您拨打虚拟方法时,您的通话将转至Base::foo()。这不一定是错的,但通常是意料之外的,因此一般禁止它。

同样在销毁期间,Derived在调用~Base()之前被销毁,因此虚拟方法调用将再次转移到Base::foo(),这通常也是意外的。

答案 1 :(得分:4)

尝试运行此示例:

struct base {
   virtual int f() const { return 0; }
   base() { std::cout << f() << "\n"; }
   ~base() { std::cout << f() << "\n"; }
};
struct derived : base {
   const int value;
   derived(int v) : value(v) {}
   virtual int f() const { return value; }
};
derived d(100);       // What should this print?

问题是当基类型的构造函数正在运行时,对象的类型仍为base,而不是derived。 Dispatch不会命中 final-overrider (从用户的角度来看,它只创建了一个derived对象)。破坏也是如此。