运行时类型识别

时间:2023-02-02 03:07:04

 运行时类型识别

当只有指针或引用指向基类型时,可以用运行时类型识别(RTTI)找到对象的动态类型。 要点: 将讲述RTTI的用途和用法。 1.      运行时类型转换 通过指针或引用来决定对象运行时类型的一种方法就是运行时类型转换(runtime cast)。这种方法可用来查看所尝试进行的转换是否正确。当由基类的指针或引用转换为派生类型时,这种方法非常有用。这时也称为向下类型转换(因为基类在派生类之上)。一般不提倡向下类型转换,但如果要进行这种转换,就需要使用类型可检查的类型转换操作符dynamic_castdynamic_cast要求使用的目标对象的类型是多态的。它在运行时使用虚函数表,所以它比其它新的类型转换操作的代价更高。由于没有空引用,所以在对引用进行类型转换时,要检查转换是否成功,譬如可以在检查到转换失败时抛出bad_cast异常。 2.      typeid操作符 typeid()可以返回对象运行时类型信息,这种操作符操作结果返回一个type_information类对象。如果是多态类型,则返回那个应用(动态类型)的大部分派生类信息;否则只给出静态类型信息。它也支持内置类型。如果把typeid应用于解析一个空指针的一个表达式中,则会引起一个bad_typeid异常抛出(该异常也包含在typeinfor中)。 1) 类型转换到中间层次类型 2) void型指针 typeid()不能与void型指针一起工作。因为当使用typeid时要求所有的类型信息都是可利用的。 3) 运用带模板的RTTI 3.      多重继承 RTTI机制必须正确地处理多重继承的复杂性,包括虚基类virtual 4.      合理使用RTTI 只在须要的时候才使用RTTI 使用虚函数多态机制的方法调用,要求我们拥有基类的控制权,当基类来自一个库或由别人控制时,RTTI就可以解决这一问题,可以派生一个新类,添加我们所需要的成员函数。当在程序主体中增加所需的新特征的代码时,则必须使用RTTI来检查该特定的类型。RTTI有时可以解决效率问题。 垃圾再生器的例子。 5.      RTTI的机制和开销 实现RTTI的典型方法是,在类的虚函数表中放入一个附加的指针。这个指针指向那个特别类型的类的type_infor结构。Typeid()操作是一个双指针的解析操作,这个代价是一个常量时间的操作。对于dynamic_cast<destination*>(source_pointer)来说,大部分情况是:检索source_pointerRTTI信息,为destination*类型取得RTTI信息。然后确定source_pointer是否属于类型destination*destination*的一个基类。因为一个基类型可以出现多次,如果是多重继承那么将更复杂。 为了dynamic_cast而使用的库程序必须从头到尾对一个基类表进行检查,dynamic_cast开销可能高于typeid(),找到一个基类比找到一个派生类更花时间。Dynamic_cast将任何一个类型与其它类型比较,在同一层次中可以进行不受限制的进行类型比较。这就增加了由dynamic_cast使用的库程序的额外开销。