【问题标题】:Why does non-pure virtual method have to be defined in base class?为什么非纯虚方法必须在基类中定义?
【发布时间】:2016-10-01 00:29:41
【问题描述】:

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

这会导致链接器错误:

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

但如果我在 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++ linker-errors pure-virtual virtual-functions


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您的补充说明
    【解决方案2】:

    来自 C++11 标准:

    10.3 虚函数

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

    定义纯虚函数也可以,但不是必须的。

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

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

    【讨论】:

      【解决方案3】:

      答案就在定义本身。如果未定义函数,则该函数是纯虚函数。然后,如果您不将其标记为纯虚拟,则必须对其进行定义。这是C++ 语言的约束。

      【讨论】:

      • 为什么没有调用的时候还要定义函数?
      • 一个函数如果没有定义就是纯虚函数”是不正确的。如果一个函数被声明为纯虚函数,那么它就是纯虚函数。一个纯虚函数可以有定义(但不是必须的)。
      猜你喜欢
      • 2021-12-25
      • 2016-10-08
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-18
      相关资源
      最近更新 更多