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

Mar*_*oun 1 c++ inheritance virtual-functions

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

我知道,如果我有一个Class Base定义虚方法foo(),那么分辨率在所有子类中foo()都是动态Base.因此,如果子类Derived重写foo()Derived::foo()调用.那么为什么在构造/销毁期间调用虚方法会让编译器感到困惑?

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

小智 5

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

类似地,在销毁期间,Derived在~Base()被调用之前被销毁,因此再次进行虚拟方法调用Base::foo(),这通常也是意外的.


Dav*_*eas 5

尝试运行这个例子:

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?
Run Code Online (Sandbox Code Playgroud)

问题在于,当基类型的构造函数运行时,对象的类型仍然是base, 而不是derived。调度不会命中最终重写者(从用户的角度来看,它只创建了一个derived对象)。同样的情况也发生在破坏中。