typeid在多态/非多态类型的工作机制及书籍代码正误疑问
typeid在多态与非多态类型中的工作机制
非多态类型场景
当typeid作用于非多态类型(类中无任何虚函数)的对象或类型名时,类型信息完全在编译期确定:
- 编译器直接根据静态类型推导结果,返回对应类型的
type_info对象,不需要访问目标对象的实际内存。 - 即使对象仅通过
extern声明而未定义,只要编译期能确定其静态类型,typeid操作也不会触发链接错误——因为不需要运行时读取对象数据。
多态类型场景
当typeid作用于多态类型(类中包含至少一个虚函数)的对象、指向多态对象的指针或引用时,类型信息在运行时确定:
- 编译器会生成代码,通过对象的虚函数表(vtable)获取其真实的动态类型,这要求对象必须实际存在(有定义),否则会触发链接错误或运行时异常。
- 如果
typeid作用于指向多态类型的空指针,会直接抛出std::bad_typeid异常。
《C++ Templates: The Complete Guide, 2nd Edition》代码解析
原文段落翻译
当且仅当未定义预处理器符号DYNAMIC时,该程序才合法。实际上,变量d未被定义,但sizeof(d)对d的引用不构成使用;而typeid(d)对d的引用仅当d是多态类型对象时才构成使用(因为通常多态typeid操作的结果要到运行时才能确定)。
关于“是否应为引用extern Decider &d”的疑问
这段代码不存在印刷错误,原因如下:
- 当
DYNAMIC未定义时,Decider是非多态类型,typeid(d)是编译期操作,编译器仅需知道d的静态类型即可生成结果,不需要访问d的实际内存——哪怕d只有extern声明没有定义,也不会触发链接错误,程序合法。 - 当
DYNAMIC定义时,Decider成为多态类型,typeid(d)需要运行时访问d的虚函数表,此时d必须有定义,否则链接器会报错,程序不合法。
原文用对象而非引用的写法,是为了更直观地对比typeid对多态/非多态对象的不同处理逻辑,完全符合C++标准的规则。
内容的提问来源于stack exchange,提问作者Dmitry Kuzminov
相关产品推荐
相关产品推荐

