GCC C ++链接器错误:未定义的引用'XXX的虚拟表',未定义的引用'ClassName :: ClassName()'

我使用Eclipse-CDT在Ubuntu x64上设置了一个C ++项目。 我基本上正在做一个你好的世界,并链接到商业第三方图书馆。

我已经包含链接到他们的库的头文件,但我仍然得到链接器错误。 除了显而易见的情况之外,是否还有其他一些可能的问题(例如,我确信我链接到了正确的库)。

  1. 有没有办法确认我连接的静态库是64位?
  2. 有没有办法确认图书馆有我期待的类(和方法)?

Eclipse说:

build立目标:LinkProblem
调用:GCC C ++链接器
 g ++ -L / home / notroot / workspace / somelib-3 / somelib / target / bin -o“LinkProblem”./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3
 ./src/LinkProblem.o:在函数`main'中:
 /home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17:对“SomeClass :: close()”的未定义引用
 ./src/LinkProblem.o:在函数SomeOtherClass中:
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148:对SomeClass :: SomeClass()的未定义引用
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148:未定义对“SomeOtherClass的vtable”的引用
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151:对SomeClass ::〜SomeClass()的未定义引用
 ./src/LinkProblem.o:在函数`〜SomeOtherClass'中:
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:未定义对“SomeOtherClass的vtable”的引用
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:对SomeClass ::〜SomeClass()的未定义引用
 /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:对SomeClass ::〜SomeClass()的未定义引用
 collect2:ld返回1退出状态
 make:*** [LinkProblem]错误1

假设这些方法是在一个库中看起来像一个sorting问题。

将库链接到可执行文件时,它们按照声明的顺序完成。
此外,链接程序将仅采用解决当前未完成依赖关系所需的方法/函数。 如果后续的库使用原来不需要的方法/函数,将会缺less依赖关系。

怎么运行的:

  • 拿所有的目标文件,并把它们合并成一个可执行文件
  • 解决目标文件之间的任何依赖关系。
  • 对于每个库的顺序:
    • 检查未解决的依赖关系,看看是否解决它们。
    • 如果这样的话将所需的部分加载到可执行文件

例:

对象需要:

  • 打开
  • BatchRead
  • BatchWrite

Lib 1提供:

  • 打开

Lib 2提供

  • BatchRead(但使用lib1:读取)
  • BatchWrite(但使用lib1:写)

如果这样链接:

gcc -o plop plop.o -l1 -l2

那么链接器将无法parsing读写符号。

但是,如果我像这样链接应用程序:

gcc -o plop plop.o -l2 -l1

然后它会正确链接。 由于l2parsing了BatchRead和BatchWrite依赖关系,但也增加了两个新的(读和写)。 当我们连接l1时,所有四个依赖关系都解决了。

这个链接器错误通常(以我的经验)意味着你已经用一个声明覆盖了一个子类中的虚函数,但没有给出该方法的定义。 例如:

class Base { virtual void f() = 0; } class Derived : public Base { void f(); } 

但是你没有给出f的定义。 当你使用这个类的时候,你会得到链接错误。 就像一个正常的链接器错误,这是因为编译器知道你在说什么,但链接器找不到定义。 这只是一个很难理解的信息。

Qt C ++会在你改变一个类的时候显示这个错误,使得它现在从QObjectinheritance(也就是说现在可以使用信号/插槽)。 运行qmake -r将调用moc并修复这个问题。

如果您通过某种版本控制与他人合作,您将需要对.pro文件进行一些更改(即添加/删除空白行)。 当其他人得到您的更改并运行make时,make会看到.pro文件已经更改并自动运行qmake。 这样可以避免你的队友重蹈覆辙。

对我来说问题变得相当模糊。 我的class级看起来像这样:

 //----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() { } virtual int foo() { return 0; } } //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" //----------------------------------------- //----------------------------------------- // main.h class derived : public base { public: virtual int foo() ; } //----------------------------------------- //----------------------------------------- // main.cpp int main () { derived d; } //----------------------------------------- 

问题出在链接器中。 我的头文件在某个库中,但是所有的虚函数都是在类声明中声明为“inline”的。 由于没有使用虚函数的代码(编译器或链接器)忽略了实际的函数体。 它也没有创buildvtable。

在我从这个类派生的主代码中,链接器试图将我的类连接到基类和他的虚表。 但是vtable被丢弃了。

解决的办法是在类声明之外声明至less一个虚函数体,如下所示:

 //----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() ; //-- No longer declared 'inline' virtual int foo() { return 0; } } //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" base::~base() { } //----------------------------------------- 

关于Qt4的问题,我不能使用上面提到的qmake moc选项。 但是,这不是问题。 我在类定义中有以下代码:

 class ScreenWidget : public QGLWidget { Q_OBJECT // must include this if you use Qt signals/slots ... }; 

我不得不删除行“Q_OBJECT”,因为我没有信号或槽定义。

我有这个错误消息。 问题是我在头文件中声明了一个虚析构函数,但是虚函数的实体实际上并没有实现。

当我们在基类中声明一个没有任何定义的虚函数的时候,这个错误也会发生。

例如:

 class Base { virtual void method1(); // throws undefined reference error. } 

将上面的声明更改为下面的声明,它将正常工作。

 class Base { virtual void method1() { } } 

在我的情况下,当我忘记在我的纯虚拟类中的一个函数中添加= 0时,出现问题。 当= 0被添加时,它是固定的。 和上面的Frank一样。

 class ISettings { public: virtual ~ISettings() {}; virtual void OKFunction() =0; virtual void ProblemFunction(); // missing =0 }; class Settings : ISettings { virtual ~Settings() {}; void OKFunction(); void ProblemFunction(); }; void Settings::OKFunction() { //stuff } void Settings::ProblemFunction() { //stuff } 

我现在也偶然发现了这个问题。 应用程序定义了一个纯虚拟接口类,并且通过共享库提供的用户定义的类应该实现该接口。 链接应用程序时,链接器抱怨共享库不会为基类提供vtable和type_info,也不能在其他地方find它们。 原来,我只是简单地忘记了使接口的方法之一是纯虚拟的(即在声明结尾省略了“= 0”)。如果不能将连接器诊断连接到根本原因。

当我尝试使用Qt的“hello world”这个东西的时候,我有这个错误信息。 通过正确运行qt moc(元对象编译器)并正确编译包括这些moc生成文件的+,问题消失了。

如果您有一个纯虚函数的基类,请确保您的基类构造函数和析构函数具有正文,否则链接器失败。

我把这个给未来的访客:

如果您在创build一个Exception对象时收到错误,那么原因可能是缺lesswhat()虚函数的定义。