关于为this question提供解决方案,我试图简化我在使用RTTI和typeid()
函数的答案中提供的代码来检索类名:
#include <iostream>
#include <string>
#include <typeinfo>
struct IDriver {
// Public virtual API:
virtual void func1() = 0;
// ...
virtual ~IDriver() {}
};
class SpecificDriver;
template<typename Derived>
class Driver : public IDriver {
public:
Driver() {
std::cout << typeid(*this).name() << std::endl;
std::cout << typeid(Derived).name() << std::endl;
}
virtual ~Driver() {}
};
class SpecificDriver : public Driver<SpecificDriver> {
public:
// Public virtual API:
virtual void func1();
virtual ~SpecificDriver() {}
};
int main() {
SpecificDriver sd;
}
Using this code导致链接器错误:
/tmp/ccXnTrfe.o: In function `main':
main.cpp:(.text.startup+0x4f): undefined reference to `typeinfo for SpecificDriver'
为什么这导致typeinfo
的未定义参考错误而不是缺少func1()
定义(它甚至没有使用BTW)?
有趣的是,当我删除所有virtual
内容时,它的工作正常:
#include <iostream>
#include <string>
#include <typeinfo>
template<typename Derived>
class Driver {
public:
Driver() {
std::cout << typeid(*this).name() << std::endl;
std::cout << typeid(Derived).name() << std::endl;
}
};
class SpecificDriver : public Driver<SpecificDriver> {
};
int main() {
SpecificDriver sd;
}
输出:
6DriverI14SpecificDriverE
14SpecificDriver
这是否真的与vtable
generation有关?
答案 0 :(得分:2)
那么为什么错过了virtual void func1();
SpecificDriver
的实施
// Public virtual API:
virtual void func1();
导致错过typeinfo
的消息?
详细答案可以在这里找到:
http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf
或此处http://www.avabodh.com/cxxin/virtualfunction.html
简短的答案,因为gcc
和clang
编译器实现
rtti
通过class
vtable
vtable
查找coliru
。
如果你编译代码没有优化,gcc会给你:
未定义引用'vtable for SpecificDriver'
未定义引用'typeinfo for SpecificDriver'
-O2
默认情况下使用auto p1 = get_ptr_to_vtable();
auto p2 = get_ptr_to_typeinfo(p1);
优化级别,因此它会像这样优化代码:
auto p2 = CONSTANT;
到
{{1}}
并仅提供有关错过的typeinfo的错误。
答案 1 :(得分:1)
基本上这个问题与g++ undefined reference to typeinfo重复。
请注意,根据标准,如果没有定义所有非纯虚函数,则程序格式错误,无需诊断:
N4582 [basic.def.odr] p3
虚拟成员函数如果不纯,则使用odr。
N4582 [basic.def.odr] p4
每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义;无需诊断。 [...]内联函数应在每个使用它的翻译单元中定义。