GCC C ++链接错误:未定义提及 '虚函数表为XXX',未定义参照 '的

2019-05-17 12:19发布

我设置了一个C ++项目,在Ubuntu 64位,使用Eclipse的CDT。 我基本上是做一个Hello World,并链接到商用第三方库。

我已经包含头文件,链接到自己的音乐库,但我仍然得到链接错误。 是否有一些可能出现的问题在这里较明显的其它(如我99%肯定,我链接到正确的库)。

  1. 有没有一种方法,以确认我链接到的64位静态库?
  2. 有没有一种方法,以确认该库具有类(和方法),我希望它有哪些?

Eclipse中说:

Building target: LinkProblem
Invoking: GCC C++ Linker
g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem"  ./src/LinkProblem.o   -lsomelib1 -lpthread -lsomelib2 -lsomelib3
./src/LinkProblem.o: In function `main':
/home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()'
./src/LinkProblem.o: In function `SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()'
./src/LinkProblem.o: In function `~SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
collect2: ld returned 1 exit status
make: *** [LinkProblem] Error 1

Answer 1:

假设这些方法是在它看起来像一个排序问题库之一。

当链接库到可执行他们在声明它们的顺序进行。
另外,链接器将只需要解决当前突出的依赖关系所需的方法/函数。 如果后续库,然后使用方法/不最初是由对象要求的功能,你将有缺少的依赖关系。

这个怎么运作:

  • 把所有的目标文件和它们合并成一个可执行
  • 解决目标文件之间的依赖。
  • 对于-各自为了库:
    • 检查未解决的依赖,看看LIB解决它们。
    • 如果是这样的负载所需的部分到可执行文件。

例:

对象要求:

  • 打开
  • BatchRead
  • BatchWrite

库1条规定:

  • 打开

库2提供

  • BatchRead(但使用LIB1:阅读)
  • BatchWrite(但使用LIB1:写)

如果链接是这样的:

GCC分局宝plop.o -L1 -L2

然后链接器将不能解决读写符号。

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

GCC分局宝plop.o -L2 -L1

然后,它会正确链接。 为L2解析BatchRead和BatchWrite依赖关系还增加了两个新的(读,写)。 当我们与L1链接未来所有四个依赖被解决。



Answer 2:

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

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

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



Answer 3:

当更改类,使得它现在自QObject继承(即,使得它现在可以使用的信号/时隙)的Qt C ++将显示这个错误。 运行QMAKE -r会打电话给商务部和解决这个问题。

如果你与他人通过某种版本控制的工作,你会想做出一些改变你的.pro文件(即添加/删除空行)。 当其他人获取更改并运行make,make会看到.pro文件已发生变化,自动运行的qmake。 这将节省你的队友从重复你的无奈。



Answer 4:

对我来说原来,这个问题是相当模糊的。 我的阶级是这样的:

//-----------------------------------------
// 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;
}
//-----------------------------------------

问题是在连接。 我的头文件在图书馆去某个地方,但所有的虚函数被宣布在类声明“内联”。 由于当时使用虚拟功能(还)没有代码,编译器或链接忽视把实际的函数体到位。 它也没有创建虚表。

在我从这个类派生我的主要代码,链接器试图在我的班级连接的基类,虚函数表了。 但虚函数表已被丢弃。

解决的办法是声明虚拟功能的类声明外体中的至少一个,如下所示:

//-----------------------------------------
// libbase.h
class base {
public:
   base() { }
   virtual ~base() ;   //-- No longer declared 'inline'

   virtual int foo() { return 0; }
};
//-----------------------------------------

//-----------------------------------------
// libbase.cpp
#include "libbase.h"
base::~base() 
{
}
//-----------------------------------------


Answer 5:

在关于问题的Qt4,我不能使用上述QMAKE MOC选项。 但是,这是没有问题的反正。 我曾在类的定义如下代码:

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

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



Answer 6:

我有此错误信息。 问题是,我宣布在头文件中的虚析构函数,但虚函数的身体实际上没有实现。



Answer 7:

当我们只是声明了一个虚函数而不在基类中的任何定义也会发生此错误。

例如:

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

}

更改上述声明下面的一个,它会正常工作。

class Base
{
    virtual void method1()
    {
    }
}


Answer 8:

在我的情况下,问题发生时,我忘了加上= 0上的一个函数在我的纯虚类。 中加入= 0时它是固定的。 同样作为上述弗兰克。

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
}


Answer 9:

我现在整个问题绊倒了。 应用程序定义的纯虚接口类,并通过共享库提供的用户定义的类是应该实现的接口。 链接应用程序时,链接器抱怨说,共享库将不提供虚函数表和TYPE_INFO基类,也不能将它们在其他地方找到。 原来,我只是忘了做的接口方法的纯虚拟的(即在声明的末尾省略了“= 0”,非常简陋,依然容易忽视和令人费解,如果您无法连接的连接诊断到根本原因。



Answer 10:

尝试的“Hello World”的时候喜欢的东西使用Qt我有此错误消息。 这些问题走了通过正确地运行QT MOC(元对象编译器)和编译+包括正确这些MOC生成的文件。



Answer 11:

如果你有一个纯虚函数的基类,请确保你的基类的构造函数和析构函数有身体,否则连接失败。



Answer 12:

我把这个为未来的用户:

如果你是在创造一个接收到错误Exception对象,那么它的原因可能是缺乏定义的what()虚函数。



文章来源: GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'