虚拟函数本质上应该有一个定义吗?

nit*_*ian 7 c++ virtual-functions undefined-reference

是否必须为虚函数定义?

请考虑以下示例程序:

#include <iostream>

using namespace std;

class base
{
   public:
      void virtual virtualfunc();
};

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

int main()
{
   derived d;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给出了链接错误:

在function base::base():: undefined引用中vtable for base

我没有基类中虚函数的定义.为什么即使我没有显式调用虚函数,也会发生此错误?

我发现有趣的是,如果我没有实例化类的对象derived,则链接错误不再存在.为什么是这样?什么实例化与上述链接错误有关?

Alo*_*ave 11

ISO C++标准指定必须定义非纯虚拟类的所有虚方法.

参考:

C++ 03标准:10.3虚函数[class.virtual]

在类中声明的虚函数应在该类中定义或声明为纯(10.4),或两者兼有; 但不需要诊断(3.2).

因此,您应该将函数设置为纯虚拟或为其提供定义.

如果您使用的是gcc,如果您不遵守此标准规范,可能会遇到一些奇怪的错误.在gcc的常见问题 doccuments它还有:

ISO C++标准指定必须定义非纯虚拟类的所有虚方法,但不要求违反此规则的任何诊断[class.virtual]/8.基于此假设,GCC将仅在翻译单元中发出隐式定义的构造函数,赋值运算符,析构函数和类的虚拟表,以定义其第一个此类非内联方法.

因此,如果您未能定义此特定方法,链接器可能会抱怨缺少明显不相关的符号的定义.不幸的是,为了改进此错误消息,可能需要更改链接器,并且不能总是这样做.

解决方案是确保定义所有非纯的虚方法.请注意,即使声明为pure-virtual,也必须定义析构函数[class.dtor]/7.


Mic*_*son 8

除非将函数定义为"纯虚拟",否则您需要提供虚函数的实现(具有其默认行为).

所以你的例子可能是:

class base
{
   public:
      void virtual virtualfunc() {} //intentionally do nothing;
};
Run Code Online (Sandbox Code Playgroud)

要么

class base
{
   public:
      void virtual virtualfunc()=0; //pure virtual;
};
Run Code Online (Sandbox Code Playgroud)