RTTI(运行时类型识别)回顾与存储位置简介
RTTI(运行时类型识别)回顾与存储位置简介
- RTTI(运行时类型识别)回顾与存储位置简介
- 1. RTTI(运行时类型识别)简单回顾
- 示例代码
- 运行结果
- 解释
- 2. RTTI 实现原理
- 详细解释
- 3. vptr、vtbl与 RTTI 的 type_info 信息创建时机
- 总结
1. RTTI(运行时类型识别)简单回顾
RTTI(运行时类型识别)是C++提供的一种机制,用于在运行时识别对象的类型。RTTI主要包括两个操作:
typeid
操作符:用于获取对象的类型信息。dynamic_cast
操作符:用于在继承层次中安全地进行类型转换。
示例代码
#include <iostream>
#include <typeinfo>class Base {
public:virtual ~Base() = default;
};class Derived : public Base {};int main() {Base* b = new Derived();// 使用 typeid 获取类型信息std::cout << "Type of b: " << typeid(*b).name() << std::endl;// 使用 dynamic_cast 进行类型转换Derived* d = dynamic_cast<Derived*>(b);if (d) {std::cout << "b is of type Derived" << std::endl;} else {std::cout << "b is not of type Derived" << std::endl;}delete b;return 0;
}
运行结果
Type of b: 7Derived
b is of type Derived
解释
-
typeid 操作符:
typeid(*b).name()
返回一个表示b
所指向对象类型的字符串。在这个例子中,输出结果是7Derived
,表示b
指向的是Derived
类型的对象。7
表示类型名称的长度,Derived 是类型的实际名称。 -
dynamic_cast 操作符:
dynamic_cast(b)
尝试将b
转换为Derived*
类型。如果转换成功,返回非空指针;否则,返回空指针。在这个例子中,转换成功,所以输出b is of type Derived
。
2. RTTI 实现原理
RTTI 的实现依赖于虚函数表(vtbl)和虚指针(vptr)。每个多态类对象都有一个指向虚函数表的指针(vptr),虚函数表中包含了指向虚函数的指针以及类型信息(type_info)。
详细解释
-
vptr(虚指针):每个多态类对象都有一个隐藏的指针,指向该对象的虚函数表。vptr 在对象构造时被初始化。
-
vtbl(虚函数表):虚函数表是一个指针数组,包含了类的虚函数指针和类型信息。每个多态类都有一个唯一的虚函数表。
-
type_info:
type_info
是一个包含类型信息的结构体。编译器在编译时为每个多态类生成一个type_info
对象,并在运行时通过虚函数表访问它。
3. vptr、vtbl与 RTTI 的 type_info 信息创建时机
- vptr(虚指针):虚函数指针
vptr
是跟着对象走的,对象创建出来了,才存在vptr
。vptr
也是属于类中的一个成员变量,它是编译器在编译的时候就插进去的,然后vptr
的赋值就是在程序运行起来后,程序员创建一个对象的时候,执行编译器插入到构造函数中的赋值代码时才给vptr
赋值的,让其指向该类所属的虚函数表。 - vtbl(虚函数表):虚函数表
vtbl
是在编译期间就确定好的,跟着类走。 - type_info:
RTTI
的type_info
信息实际上也是编译期间就创建好的。程序员能做的事情就是去读取这些信息。所以不难发现,不管生成多少个类对象,取得的type_info
所指向的地址都是相同的。也就是说,这个信息也是基于类的。
总结
- RTTI:运行时类型识别用于在运行时识别对象的类型,主要通过
typeid
和dynamic_cast
操作符实现。 - 实现原理:RTTI 依赖于虚函数表(vtbl)和虚指针(vptr),通过它们在运行时获取类型信息。
- **type_info **:编译器在编译时为每个多态类生成一个
type_info
对象,并在运行时通过虚函数表访问它。