c++ - GCC C++ 链接器错误: 未定义对''的vtable引用,未定义对'类名的未定义引用:: classname ( )''

  显示原文与译文双语对照的内容

我正在设置一个 C++ 项目,在 Ubuntu x64上使用 Eclipse-CDT 。 我基本上是在做一个hello世界 3,并链接到一个商业rd聚会库。

我已经包含了头文件,链接到它们的库,但我仍然得到链接器错误。 除了明显的( 比如 ) 之外还有一些可能的问题。 我 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
时间: 原作者:

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

将库链接到可执行文件时,它们按照声明的顺序执行。
同时链接器将只接受解析当前oustanding依赖所需的方法/函数。 如果随后的库使用的方法/函数不是对象所需要的,这些对象将丢失依赖关系。

它的工作原理:

  • 获取所有对象文件并将它们合并到一个可执行文件中
  • 在对象文件中解析任何 dependecies 。
  • Foreach库按顺序:
    • 检查未解析的依赖项,看看lib是否解析它们。
    • 如果是这样,则将需要的部分加载到可执行文件中。

例如:

对象需要:

  • 打开"%s"
  • 关闭
  • BatchRead
  • BatchWrite

Lib 1提供:

  • 打开"%s"
  • 关闭
  • 已读
  • 写入

Lib 2提供

  • BatchRead ( 但使用 lib1:read )
  • BatchWrite ( 但使用 lib1:write )

如果链接如下:

gcc -o plop plop.o -l1 -l2

然后链接器将无法解析读取和写入符号。

但是如果我这样 linki:

gcc -o plop plop.o -l2 -l1

然后它会正确链接。 当l2解析BatchRead和BatchWrite依赖关系时,还会添加两个新的( 读写) 。 当我们用l1链接时,所有四个依赖项都被解析。

原作者:

这个链接器错误通常是( 以我的经验) 意味着你已经在子类中重写了一个虚函数,但没有为该函数提供定义。 例如:


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

但你还没有给出f的定义。 使用该类时,会得到链接器错误。 很像普通的链接器错误,这是因为编译器知道你正在谈论什么,但是链接器找不到定义。 这只是一个很难理解的消息。

原作者:

已经提到了,但我想澄清一点。

Qt C++ 将显示这个错误当你改变一个类,它现在继承自 QObject ( IE 以便它现在可以使用信号/插槽) 。 运行 R 将调用并修复这里问题。

如果你通过某种版本控制与其他人合作,你将希望对. pro 文件( IE 添加/删除空行) 进行一些更改。 当其他人获取你的更改并运行来杯时,来杯会看到. pro 文件已经更改并自动运行了。 这将避免你的队友重复你的挫败。

原作者:

我原来的问题是非常模糊的。 我的类类似于:


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

问题在链接器中。 我的头文件在某个库中运行,但是所有虚函数都在类声明中声明为'行内'。 由于没有使用虚函数( 还还还)的代码,编译器或者链接器忽略将实际函数体放置到位。 它也未能创建 vtable 。

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

解决方案就是申报至少一个虚函数的类声明之外的身体,是这样的:


//-----------------------------------------
//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的问题,我不能使用上面提到的moc选项。 但这不是问题。 在类定义中我有以下代码:


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

由于没有定义信号或者插槽,我不得不删除行"q_object"。

我有这个错误消息。 问题是我在头file,中声明了一个虚拟析构函数,但是虚函数'body was实际上没有实现。

在我的例子中,当我忘记将=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
}

当我们简单地声明虚函数而不在基类中定义任何定义时,也会发生这里错误。

例如:


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

}

将上面的声明更改为下面的声明,它将工作得很好。


class Base
{
 virtual void method1()
 {
 }
}

原作者:

我现在也遇到了这个问题。 应用程序定义了一个纯虚拟接口类,通过共享库提供的user-defined类应该实现接口。 链接应用程序时,链接器抱怨共享的lib不会为基类提供vtable和 type_info,也不会在其他地方找到。 原来我忘了做一个接口纯虚拟( 例如 )的方法。 省略了声明末尾的"= 0"。 非常简单,如果你无法将链接器诊断连接到 root 原因,仍然容易忽略和困惑。

原作者:

我在尝试"欢迎世界"时遇到了这个错误消息。 正确运行 qt ( 元对象编译器) 和 compiling+including moc-generated文件时出现问题。

...