cpp-expert/rtti-typeid:RTTI 与 typeid 演示
本目录收录 languages/cpp/expert/rtti-typeid.md 的完整可运行代码与实测数据。
要回答的问题:typeid 怎么知道对象的动态类型?typeinfo 藏在哪?关闭 RTTI 能省多少体积?
| 文件 | 说明 |
|---|---|
main.cpp | typeid 运行期/编译期两种形态 + dynamic_cast 各情形 |
nortti.cpp | 同一类层次但不用 RTTI(可 -fno-rtti 编译,作体积对照) |
Makefile | make run 运行;make symbols 看 typeinfo/vtable 符号;make sizes 对比体积 |
run-remote.sh | 服务器一键实测脚本 |
编译与运行
bash
make # 构建 rtti(开 RTTI)与 nortti(-fno-rtti -fno-exceptions)
make run # 运行,观察 typeid 输出与 dynamic_cast 结果
make symbols # nm -C 看 typeinfo / vtable 符号
make sizes # RTTI 开/关体积对比实测输出(Linux, g++ 4.8.5, -std=c++11)
运行输出
typeid: 4Base
typeid: 3Mid
typeid: 4Leaf
p1 动态类型是 Base? 1
p2 动态类型是 Mid? 1
p3 动态类型是 Leaf? 1
p1 -> Leaf*: null
p3 -> Leaf*: ok
非多态 typeid: Z4mainE5Plaintypeid 对多态对象给出动态类型(传 Leaf& 得到 4Leaf);dynamic_cast 向下转换失败返回 null,成功返回指针;非多态类型 typeid 只给编译期类型。
typeinfo / vtable 符号(nm -C 摘要)
0000000000400e40 r typeinfo for main::Plain
0000000000400e60 V vtable for Leaf
0000000000400ea0 V vtable for Mid
0000000000400ee0 V vtable for Base
0000000000400f08 V typeinfo name for Leaf
0000000000400f10 V typeinfo for Leaf
0000000000400f28 V typeinfo name for Mid
0000000000400f30 V typeinfo for Mid
0000000000400f48 V typeinfo name for Base
0000000000400f50 V typeinfo for Base
0000000000602080 V vtable for __cxxabiv1::__class_type_info@@CXXABI_1.3多态类每个都有 typeinfo + typeinfo name + vtable;非多态的 main::Plain 也因 typeid 被使用而产生了 typeinfo(局部符号 r),但没有 vtable。
RTTI 开/关体积对比
== rtti(开 RTTI) ==
text data bss dec hex filename
4145 652 192 4989 137d rtti
file: 22200
== nortti(-fno-rtti -fno-exceptions) ==
text data bss dec hex filename
2402 604 4 3010 bc2 nortti
file: 14952关闭 RTTI + 异常后 text 段减少约 1743 B(42%),文件减小约 7 KB。