RTTI(Run-time Type Identification)

一个定义良好的类层次结构应该为基类中声明的每一个虚成员函数定义有意义的操作。

RTTI(Run-time Type Identification)机制

为了能够在运行时获得对象的类型信息type_info,C++增加了两个运算符:typeid和dynamic_cast<>。type_info常用的3个成员函数为operator==()、operator!=()和name()。


dynamic_cast<>用来执行运行时类型识别和转换。

其语法为:dynamic_cast<dest_type>(src)

其中,dest_type就是转换的目标类型,而src则是被转换的对象。其行为可以描述为:如果运行时src和dest_type确实存在is-a关系,则转化可进行,否则转换失败。


提示:

(1)dynamic_cast<>可以用来转换指针和引用,但是不能转换对象。(当目标对象是某种类型的指针时,如果转换成功则返回目标类型的指针,否则返回NULL;当目标类型为某种类型的引用时,如果成功则返回目标类型的引用,否则抛出std::bad_cast异常,因为不存在NULL引用)

(2)dynamic_cast<>,通过对象的vptr检查位于其类型的vtable第一个slot的type_info对象而得知的。dynamic_cast<>只能用于多态类型对象(拥有虚函数或虚拟继承),否则将导致编译时错误。


dynamic_cast<>可实现两个方向的转换:upcast和downcast.

@upcast:把派生类型的指针、引用转换成基类型的指针或引用(实际上这可以隐式的进行,不必显式地转换);

@downcast:把基类型的指针或引用转换成为派生类型的指针或引用。(如果基类型的指针或引用确实指向一个这种派生类的对象,转换就会成功,否则就会失败)。


提示:

@为了支持dynamic_cast<>运算符,RTTI机制必须维护一棵继承树,即base class table模型(或者类似的索引表格)。只有这样,dynamci_cast<>才能够通过遍历其继承树来确定一个待转换的对象和目标类型之间是否攒在is-a关系。

@typeid()运算符不需要遍历继承树。


注意:使用RTTI时要注意以下问题

@如果你的编译器没有打开RTTI支持,请打开它(参考编译器手册);

@要想使用RTTI,对象所属类型必须是多态类;

@如果要用dynamic_cast<>转换一个引用,要保证程序有一条catch()语句来出来std::bad_cast异常;

@如果试图用typeid来检索NULL指针所指对象的类型信息,像这样typeid(*p);//p==NULL   将抛出std::bad_typeid异常;

@当用dynamic_cast<>转换一个指针的时候,要记住检查返回值是否为NULL。


RTTI的开销:

无论基本类型还是用户定义类型,都需要额外的内存来存放type_info对象。




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值