为什么我会使用虚拟和具体的类获得"未定义的符号... typeinfo ... vtable"?

fea*_*ool 5 c++ clang++

我正在重新学习C++(意思是:温柔地对待我!:).我有一个Node带有抽象方法(step())的超类(),它必须在子类(TestNode)中实现.它编译没有错误,没有任何警告,但链接它导致:

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)
Run Code Online (Sandbox Code Playgroud)

据我所知,我已经定义了"第一个非内联虚拟成员函数"(即TestNode::step()).

我已经仔细阅读错误消息,我读过的博客文章在这里,并期待其他一些SO职位(未定义的符号"虚函数表为..."和"所属类别的...?",如何找到未定义的虚拟类的函数,c ++缺少vtable错误),但我觉得没有接近启蒙.

我错过了什么?

这是整个计划.

#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;
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 10

问题是你没有提供任何实现Node::step().如果你真的希望Node没有步骤的实现,那么你应该使它成为一个纯虚函数Node::step(int count) = 0,从而使Node成为一个抽象类(你不能直接实例化它).否则,为Node :: step定义一个实现.


lpa*_*app 10

据我所知,我已经定义了"第一个非内联虚拟成员函数"(即TestNode :: step()).

你似乎把定义与声明混淆了.你在基类中所拥有的只是没有定义的声明,即实现.

您需要将其设置为纯虚拟或实现它,即使它只是一个空{}.

class Node {
public:
    virtual Node& step(int count);
 };
Run Code Online (Sandbox Code Playgroud)

快速解决方法可能是:

class Node {
public:
    virtual Node& step(int count) = 0;
                               // ^^^ making it pure virtual
 };
Run Code Online (Sandbox Code Playgroud)

要么:

class Node {
public:
    virtual Node& step(int count) { };
                               // ^^^ empty implementation for now
 };
Run Code Online (Sandbox Code Playgroud)

  • @fearless_fool:我不确定您为什么这么担心声誉。这与站点的Q / A有关,因为选定的答案弹出到顶部。无论哪种方式,这都是您的决定,因此,如果您认为这是一个技术上更好的答案,那就去做。 (2认同)