为什么非纯虚方法必须在基类中定义?

Mar*_*n G 0 c++ virtual-functions linker-errors pure-virtual

在这种特殊情况下,为什么我必须在基类中定义非纯虚方法以避免链接器错误?

这会产生链接器错误:

class A
{
  public:
  virtual ~A(){}
  virtual void foo() = 0;
  virtual void bar();
};

class B : public A
{
  public:
  void foo()
  {
  }
  void bar()
  {
  }
};

int main()
{
    B b;
}
Run Code Online (Sandbox Code Playgroud)

输出:

/tmp/cc5E8Tit.o: In function `A::~A()':
:(.text._ZN1AD2Ev[_ZN1AD5Ev]+0x13): undefined reference to `vtable for
A' /tmp/cc5E8Tit.o:(.rodata._ZTI1B[_ZTI1B]+0x10): undefined reference
to `typeinfo for A' collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

但如果我在类中定义 bar 方法,A它链接正常:

class A
{
  public:
  virtual ~A(){}
  virtual void foo() = 0;
  virtual void bar(){}
};

class B : public A
{
  public:
  void foo()
  {
  }
  void bar()
  {
  }
};

int main()
{
    B b;
}
Run Code Online (Sandbox Code Playgroud)

...没有链接器错误。

为什么是这样?

Rev*_*lot 5

R Sahu已经提供了与此相关的标准引用,我将提供稍微更长的解释为什么会发生错误 \xe2\x80\x94 有时,如果不使用函数,您可以不定义函数,但在这种情况下不行。

\n\n

总是使用虚函数。它们的地址用于虚拟表中,这些虚拟表是为每个具有虚拟函数的类构建的,并且用于动态调度。

\n\n

链接器发出错误,因为基类A构造函数设置了指向基类虚拟表的指针,虚拟表包含指向的指针bar,并且链接器无法找到bar成员函数的定义来查找其地址。

\n