typeid用于运行时类型查询,返回std::type_info引用;限制包括:仅多态类型支持动态类型识别、需启用RTTI、空指针解引用抛bad_typeid、跨编译单元比较不可靠、对数组/引用/CV限定符敏感。
typeid 是 C++ 提供的运行时类型查询操作符,返回一个 std::type_info 引用,可用于获取对象或类型的静态/动态类型信息。但它不是万能的:对非多态类型(即不含虚函数的类),typeid 返回的是**编译期类型**,而非实际对象类型。
-frtti,MSVC 默认启用)typeid(*ptr) 会抛出 std::bad_typeid 异常typeid 不支持比较不同编译单元中定义的同名类(因 type_info::name() 可能不一致,且 operator== 的行为依赖实现)typeid(int[3])、typeid(const int&) 都产生独立的 type_info
RTTI 的核心价值之一是支撑 dynamic_cast 的安全向下转型。它只对**多态类型**(含至少一个虚函数)生效,并在运行时检查继承关系是否成立。失败时,对指针返回 nullptr,对引用抛出 std::bad_cast。
static_cast 在编译期完成转换,不验证实际对象类型,误转会导致未定义行为dynamic_cast 要求源类型必须是多态的;否则编译报错:error: cannot dynamic_cast ... which is not a polymorphic type
dynamic_cast 还能正确调整 this 指针偏移,static_cast 无法保证这点不能靠 typeid 或 dynamic_cast 是否“报错”来探测——它们的行为依赖编译选项和类型结构。最可靠的方式是在编译期用类型特征:
static_assert(std::is_polymorphic_v, "MyClass must be polymorphic for RTTI use");
std::is_polymorphic_v 在 中定义,返回 true 当且仅当 T 有虚函数(包括虚析构)dynamic_cast 仍非法;而 typeid 虽可用,但结果与 static_cast 等效,无动态意义
TTI 相关错误和调试建议RTTI 问题往往表现为静默错误或崩溃,而不是编译失败。典型现象包括:
dynamic_cast 转换非多态类型 → 编译失败,看清错误信息里的 “not a polymorphic type”typeid → 抛 std::bad_typeid,应先判空typeid 比较 → type_info::operator== 可能返回 false,即使名字相同;避免跨模块直接比较 type_info,改用字符串名(但注意 name() 无标准格式)-fno-rtti)后仍用了 dynamic_cast 或 typeid → 链接失败或编译报错,错误提示通常明确真正麻烦的是误以为 typeid 能替代接口设计:比如用一长串 if (typeid(obj) == typeid(A)) {...} else if (typeid(obj) == typeid(B))...。这不仅脆弱、难维护,还绕过了虚函数机制本应提供的扩展性。遇到这种代码,优先考虑重构为访问者模式或 std::variant(C++17)。