从构造函数调用虚函数和纯虚函数

nit*_*ian 5 c++ constructor virtual-functions compiler-errors dynamic-binding

当我从基础构造函数调用虚函数时,编译器不会给出任何错误.但是当我从基类构造函数调用纯虚函数时,它会产生编译错误.

考虑下面的示例程序:

#include <iostream>

using namespace std;
class base
{
   public:
      void virtual virtualfunc() = 0;
      //void virtual virtualfunc();
      base()
      {
         virtualfunc();
      }
};

void base::virtualfunc()
{
   cout << " pvf in base class\n";
}

class derived : public base
{
   public:
   void virtualfunc()
   {
      cout << "vf in derived class\n";
   }
};

int main()
{
   derived d;
   base *bptr = &d;
   bptr->virtualfunc();

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里可以看出纯虚函数有一个定义.我期望在bptr->virtualfunc()执行时调用基类中定义的纯虚函数.相反,它给出了编译错误:

错误:从构造函数调用的抽象虚拟`virtual void base :: virtualfunc()'

这是什么原因?

Alo*_*ave 10

不要从构造函数调用纯虚函数,因为它会导致未定义的行为.

C++ 03 10.4/6状态

"可以从抽象类的构造函数(或析构函数)调用成员函数;对于从这样的构造函数创建(或销毁)的对象,直接或间接地对纯虚函数进行虚拟调用(10.3)的效​​果(或析构函数)未定义."

您收到编译错误,因为您尚未virtualfunc()在Base类中定义纯虚函数.为了能够召唤它,它必须有一个身体.

无论如何,应该避免在构造函数中调用纯虚函数,因为这样做是未定义的行为.

  • @LinuxPenseur:根据标准,它是未定义的行为,它是一种实现的质量,告诉你*之前*它可能在运行时崩溃.如果你真的想从构造函数中调用该函数,请禁用虚拟调度机制:`base :: virtualfunc()`这应该消除错误(同时在用户代码中明确表示你正在调用的内容.请注意,在某些情况下编译器有问题的代码实际上会调用`base :: virtualfunc()`(即使是纯虚拟的,只要它被定义)而不会崩溃,但这只是UB的不同版本. (2认同)