vtable for .. referenced from compile error xcode

19

我在编译iPhone项目时遇到以下错误:

"vtable for oned::MultiFormatUPCEANReader", referenced from:
      __ZTVN4oned23MultiFormatUPCEANReaderE$non_lazy_ptr in MultiFormatUPCEANReader.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

有人知道我该如何修复它吗?

5个回答

41

问题似乎在于我在MultiFormatUPCEANReader类中声明了构造函数和析构函数,但没有为析构函数编写函数体,这导致了这个恼人的问题。希望这能帮助某些人解决他们的编译错误。 这是一个信息很少的糟糕的编译器错误!


4
同意,错误信息很糟糕。我遇到了这个问题,因为基类中的虚方法没有被实现。 - Nick
1
感谢您回答这个问题——它是“vtable for referenced from”在谷歌上的第一个搜索结果——为我节省了很多时间。 - noamtm
老兄,你真是救星! - pyrometer
尽管我已经为析构函数编写了函数体,但仍然出现vtable错误。我可能还漏掉了其他什么吗? - Naveen
1
@Nick -- 我之前也因为基类中的虚方法没有实现而遇到了这个错误。当我在声明后添加一个简单的 {} 时,错误消失了。 - Paul

14

通常情况下,这是缺失vtable问题:C++ FAQ Lite 23.10

来自Internet Archive:

如果您收到以下形式的链接错误:“Error: Unresolved or undefined symbols detected: virtual table for class Fred”,则可能在类Fred中有未定义的虚拟成员函数。

编译器通常会为具有虚拟函数的类创建一个名为“virtual table”的神奇数据结构(这就是它处理动态绑定的方式)。通常情况下,您根本不需要了解它。但是,如果您忘记为类Fred定义虚拟函数,则有时会收到此链接器错误。

以下是详细信息:许多编译器将这个神奇的“virtual table”放在定义类中的第一个非内联虚拟函数的编译单元中。因此,如果Fred中的第一个非内联虚拟函数是wilma(),编译器将在看到Fred::wilma()的编译单元中放置Fred的虚拟表。不幸的是,如果您意外忘记定义Fred::wilma(),那么您可能会得到一个“Fred的虚拟表未定义”的错误消息,而不是“Fred::wilma()未定义”。真是太遗憾了。


7

在我的情况下,这是一个在基类中定义的纯虚方法,在派生类中被声明但未实现(更具体地说,是vtable中的第一个虚拟方法),例如:

class Base
{
public:
  virtual int foo() = 0;
  virtual int bar() = 0;
};

class Derived : public Base
{
public:
  Derived() {}
  ~Derived() {}

  virtual int foo(); // <-- causes this obscure linker error
  virtual int bar() {return 0;}
};

4

当一个人忘记在cpp文件中方法定义前面放置类名时,就会出现相同的错误 - 就像我刚才所做的那样。这不是xcode的问题,我正在使用cmake进行构建和gcc作为编译器(通常与xcode一起使用)。


4
对我来说,这是一个XCode的问题,因为我拥有相同的项目并能成功编译。
在我的文件Foo.h中,我有构造函数和析构函数,它们都是在.cpp文件中实现的。但我还有另一个类,我在Foo.h中有它,但它的实现不在.cpp中,而是在Foo.h中。 因此,我需要将Foo.h文件添加到XCode项目中 -> Targets ->“TragetName” -> BuildSources中,这个问题就解决了。
希望这可以帮到你。

现在它被称为“编译源代码”,但对我来说完全有效! - DiCaprio

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