我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
当前回答
引用gcc手册:
对于多态类(具有虚函数的类),type_info对象与虚表[…对于所有其他类型,我们在使用type_info对象时写出type_info对象:当将' typeid'应用到表达式、抛出对象或在catch子句或异常规范中引用类型时。
在同一页稍早的地方
如果类声明了任何非内联、非纯虚函数,则选择第一个虚函数作为类的“key方法”,虚表只在定义key方法的转换单元中发出。
因此,当“key方法”缺少它的定义时,就会发生这个错误,正如前面提到的其他答案。
其他回答
在我的例子中,我使用了带有头文件等文件的第三方库。我子类化了一个类,当我尝试实例化我的子类时,发生了这样的链接错误。
正如@sergiy所提到的,知道这可能是“rtti”的问题,我设法通过将构造函数实现放在单独的.cpp文件中并将“-fno-rtti”编译标志应用到文件中来解决它。它工作得很好。
由于我仍然不太清楚这个链接错误的内部,我不确定我的解决方案是否通用。然而,我认为在尝试@francois提到的适配器方式之前值得一试。当然,如果所有源代码都可用(不是在我的情况下),最好在可能的情况下使用'-frtti'重新编译。
还有一件事,如果你选择尝试我的解决方案,试着让单独的文件尽可能简单,不要使用c++的一些花哨的功能。特别注意boost相关的事情,因为它很大程度上依赖于rtti。
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.
在基类(抽象基类)中声明虚析构函数,因为不能将析构函数声明为纯虚函数,所以要么必须在抽象类中定义它,就像virtual ~base(){}这样的虚拟定义,要么在任何派生类中定义。
如果你没有做到这一点,你将在链接时以一个“未定义的符号”结束。 因为VMT在根据派生类中的实现更新表时,为所有纯虚函数提供了一个带有匹配NULL的条目。但对于非纯虚函数,则需要在链接时定义,以便更新VMT表。
使用c++filt来要求符号。比如$c++filt _ZTIN10storageapi8BaseHostE 将输出类似"typeinfo for storageapi::BaseHost"的内容。
前面的答案是正确的,但是这个错误也可能是由于试图对没有虚函数的类的对象使用typeid而导致的。c++ RTTI需要虚表,因此希望对其执行类型标识的类至少需要一个虚函数。
如果希望类型信息作用于一个实际上不需要任何虚函数的类,可以将析构函数设为虚函数。
引用gcc手册:
对于多态类(具有虚函数的类),type_info对象与虚表[…对于所有其他类型,我们在使用type_info对象时写出type_info对象:当将' typeid'应用到表达式、抛出对象或在catch子句或异常规范中引用类型时。
在同一页稍早的地方
如果类声明了任何非内联、非纯虚函数,则选择第一个虚函数作为类的“key方法”,虚表只在定义key方法的转换单元中发出。
因此,当“key方法”缺少它的定义时,就会发生这个错误,正如前面提到的其他答案。