C++实现机制RTTI

运行时类型识别(run-time type identification, RTTI)的功能由两个运算符实现:

  • typeid运算符,用于返回表达式的类型。
  • dynamic_cast<>运算符,用于将基类的指针或引用安全的转换成派生类的指针或引用。

C++中没有JAVA中的反射机制,在运行时获得任何对象的类型信息,通常类型信息还非常丰富。C++只针对内置类型和多态的自定义类型实现了RTTI。C++引入了运行时类型信息,实际上将对象分为了两部分。

  • 一种包含了类型信息,可以在运行时获取类型信息
  • 一种没有包含类型信息

    We cannot impose the burden of being able to identify an object at run-time on built-in types such as int and double without unacceptable costs in run-time. —[C++之父Stroustrup]

按照C++之父的说法他没有为所有对象引入运行时机制的原因是,有些对象根本不需要,并且负担不起运行时获取类型信息的开销。为了不使语言设计复杂化,并且在对多态类型引入RTTI机制已经足够的情况下,只为多态类型引入了RTTI。其中通常放在virtual table中的第一个槽(slot)内,GCC会将type_info存放在虚表的第一个槽,而Visual Studio会将type_info存放在虚表的最后,其实实现方式大同小异。如下图所示:
这里写图片描述

如果通过对象来获取类型信息,则可能的实现方式就是:

((type_info*)(ptr->vptr[0]))->_type_descriptor;

获取到type_info的object后,再调用runtime library函数与class type进行比对,这种方式显然会带来很大的运行时开销。

另外需要注意的是,当dynamic_cast<>用于引用时需要注意:

const Derived& d = dynamic_cast<const Derived&>(b);

因为不存在所谓的空引用,如果转换不成功的话程序会抛出名为std::bad_cast的异常。

另一种常用的RTTI使用方式就是typeid(),typeid()会返回对象的类型信息,虽然这种方式很方便,但是我们也不能滥用这种方式来代替虚函数,这种方式扩展性不是很好,总之尽量不要使用typeid来代替虚函数的功能。

当然这只是一个示意图,真正编译器实现的时候要比这个复杂的多,有兴趣的可以看一看MSVC在RTTI上的实现方式《Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值