为什么非纯虚方法一定要定义在baseclass中?

Why does non-pure virtual method have to be defined in base class?

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

这给出了链接器错误:

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;
}

输出:

/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

但是如果我在 class A 中定义 bar 方法,它链接就可以了:

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;
}

...没有链接器错误。

这是为什么?

答案就在定义本身。如果一个函数没有定义,它就是纯虚函数。然后,如果您不将其标记为纯虚拟,则必须定义它。这是 C++ 语言的限制。

来自 C++11 标准:

10.3 Virtual functions

11 A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).

定义一个纯虚函数是可以的,但没有必要。

如果声明为纯虚函数但未声明为纯虚函数,则需要定义虚函数

即使语言不需要它,链接器也会抱怨,这很好。

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

总是使用虚函数。它们的 地址 用于虚拟 tables,虚拟 tables 是为每个 class 构建的,具有虚拟功能,用于动态调度。

链接器发出错误,因为 base class A 构造函数设置指向 base class virtual table 的指针,virtual table 包含指向 bar 并且链接器找不到 bar 成员函数的定义来查找其地址。