为什么我在虚拟类和具体类中使用时出现“Undefined symbols ... typeinfo ... vtable”?

6

我正在重新学习C++(意思是:请温柔对待我!:)。我有一个超类(Node),其中包含一个必须在子类(TestNode)中实现的抽象方法(step())。它可以编译而没有任何错误和警告,但链接它会产生以下结果:

bash-3.2$ g++ -Wall -o ./bin/t1 src/t1.cpp
Undefined symbols for architecture x86_64:
  "typeinfo for test::Node", referenced from:
      typeinfo for test::TestNode in t1-9f6e93.o
  "vtable for test::Node", referenced from:
      test::Node::Node() in t1-9f6e93.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

据我所知,我已经定义了“第一个非内联虚成员函数”(即TestNode::step())。我仔细阅读了错误消息,阅读了这里的博客文章,并查看了许多其他SO帖子(Undefined symbols "vtable for ..." and "typeinfo for..."?, How to find undefined virtual functions of a classes, and c++ a missing vtable error),但是我感觉离启蒙还有很远的路要走。我错过了什么?以下是整个程序的内容。
#include <stdio.h>

namespace test {

  class Node {
  public:
    virtual Node& step(int count);
  };

  class TestNode : public Node { 
  public:
    TestNode();
    ~TestNode();
    TestNode& step(int count);
  };

  TestNode::TestNode() { }
  TestNode::~TestNode() { }
  TestNode& TestNode::step(int count) {
    printf("count = %d\n", count);
    return *this;
  }

} // namespace test    

int main() {
  return 0;
}
2个回答

13
据我所知,我定义了“第一个非内联虚成员函数”(即TestNode::step())。
您似乎混淆了定义和声明。在基类中,您只有声明而没有定义,即实现。
您需要将其设置为纯虚拟的,或者即使它只是空的 {},也需要实现它。
class Node {
public:
    virtual Node& step(int count);
 };

一个快速的解决方法可能是:

class Node {
public:
    virtual Node& step(int count) = 0;
                               // ^^^ making it pure virtual
 };
或者:
class Node {
public:
    virtual Node& step(int count) { };
                               // ^^^ empty implementation for now
 };

好的(完整的)回答 - 谢谢。为了公平起见,@Daniel在你之前几分钟给出了正确的答案,所以他得到了一个勾号。 - fearless_fool
考虑到您的声誉(15.7k),您不觉得您可以慷慨一点,把这个问题让给丹尼尔(声望313)吗? :) 此外,他的回答完全回答了我的问题:我在原始问题中说过,我想将Node :: step()函数设置为虚函数,并要求子类实现它。 他的回答正是如此。 - fearless_fool
2
@fearless_fool:我不确定你为什么如此关注声誉。它与网站的问答有关,因为选定的答案会显示在顶部。这是你的决定,所以如果你认为那是一个技术上更好的答案,就去选择它吧。 - László Papp

13

问题在于你没有为 Node::step() 提供实现。如果你希望 Node 中没有 step 的实现,那么应该将其定义为纯虚函数 Node::step(int count) = 0,从而使 Node 成为抽象类(不能直接实例化)。否则,请为 Node::step 定义实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接