我只是遇到了以下错误:

(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的

为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?


当前回答

I encounter an situation that is rare, but this may help other friends in similar situation. I have to work on an older system with gcc 4.4.7. I have to compile code with c++11 or above support, so I build the latest version of gcc 5.3.0. When building my code and linking to the dependencies if the dependency is build with older compiler, then I got 'undefined reference to' error even though I clearly defined the linking path with -L/path/to/lib -llibname. Some packages such as boost and projects build with cmake usually has a tendency to use the older compiler, and they usually cause such problems. You have to go a long way to make sure they use the newer compiler.

其他回答

前面的答案是正确的,但是这个错误也可能是由于试图对没有虚函数的类的对象使用typeid而导致的。c++ RTTI需要虚表,因此希望对其执行类型标识的类至少需要一个虚函数。

如果希望类型信息作用于一个实际上不需要任何虚函数的类,可以将析构函数设为虚函数。

如果你要将一个。so链接到另一个。so,还有一种可能性是在gcc或g++中使用"-fvisibility=hidden"进行编译。如果两个.so文件都是用"-fvisibility=hidden"构建的,并且key方法不相同。so作为另一个虚函数的实现,后者将看不到前者的虚表或typeinfo。对于链接器来说,这看起来像一个未实现的虚函数(就像paxdiablo和cdleary的答案一样)。

在这种情况下,必须为基类的可见性做出例外

__attribute__ ((visibility("default")))

在类声明中。例如,

class __attribute__ ((visibility("default"))) boom{
    virtual void stick();
}

当然,另一个解决方案是不使用"-fvisibility=hidden "。这使得编译器和链接器的事情变得复杂,可能会损害代码的性能。

我刚才有很多这样的错误。我将一个只包含头文件的类拆分为一个头文件和一个cpp文件。但是,我没有更新我的构建系统,所以cpp文件没有被编译。除了在头文件中声明但未实现的函数的未定义引用之外,我得到了很多此类typeinfo错误。

解决方案是重新运行构建系统来编译和链接新的cpp文件。

在我的例子中,它是一个接口类中的虚函数,没有定义为纯虚函数。

class IInterface
{
public:
  virtual void Foo() = 0;
}

我忘记了= 0位。

引用gcc手册:

对于多态类(具有虚函数的类),type_info对象与虚表[…对于所有其他类型,我们在使用type_info对象时写出type_info对象:当将' typeid'应用到表达式、抛出对象或在catch子句或异常规范中引用类型时。

在同一页稍早的地方

如果类声明了任何非内联、非纯虚函数,则选择第一个虚函数作为类的“key方法”,虚表只在定义key方法的转换单元中发出。

因此,当“key方法”缺少它的定义时,就会发生这个错误,正如前面提到的其他答案。