一 RTTI(Run-Time Type Identification):typeid和dynamic_cast
(一)功能:
*通过运行时类型识别,程序能够使用基类的"指针或引用"来检索这些指针或引用所指对象的实际派生类型(typeid)。
*RTTI是在我们只有一个指向基类的指针或引用时确定一个对象的准确类型。
*当拥有基类的引用或指针时,但需要执行不是基类组成部分的派生类操作的时候,需要动态的强制类型转换(dynamic_cast)。从基类指针获得派生类行为的最好方法是通过虚函数,当使用虚函数时,编译器自动根据对象的实际类型选择正确的函数。注意区别:通过虚函数机制,不能调用派生类的非虚函数,但是通过dynamic_cast转换成功后的指针或引用可以调用派生类的非虚函数成员。
*RTTI的两种机制比虚函数更容易出错:程序员必须知道应该将对象强制转换为哪种类型,并且必须检查是否转换成功。
(二)这些操作符只对带有一个或多个虚函数的类返回动态类型信息,对于其他类型返回静态(编译时)类型信息。
二 RTTI的两种使用方法:
(一)typeid操作符:返回指针或引用所指对象的实际类型。
(1)形式:typeid(expression).
*返回这个表达式的类型信息。
*如果表达式的类型是类类型且该类包含一个或多个虚函数,则表达式的动态类型可能不同于它的静态编译时类型。
(2)用途:比较两个表达式的类型是否相等;比较表达式类型与特定类型想比较。
base *ptr1;
derived *ptr2;
if(typeid(*ptr1)==typeif(*ptr2))
{
/*两个类型比较,注意是指针的解引用*/
}
if(typeif(*ptr1)==typeid(derived))
{
/*表达式与特定类型比较.当ptr1指向detived时相等。*/
}
if(typeif(ptr1)==typeif(derived))
{/*永远不相等,测试表达式应是*ptr1*/}
*typeid操作符的结果是名为type_info的标准类类型对象的引用。
*type_info类的定义随编译器而变化。
*标准保证所有实现提供的操作:
~t1==t2:类型相同返回true,反之返回false.
~t1!=t2:同上反之。
(二)dynamic_cast操作符:将基类指针或引用安全地转换为派生类型的指针或引用。
(1)功能:将基类类型的指针或引用安全地转换为派生类类型的指针或引用。
(2)条件:
*派生体系中必须有虚函数,即多态,否则编译器报错。
*只有基类指针指向派生类对象时才转换成功。
(3)使用:
if(Derived *derivedPtr=dynamic_cast<Derived*>(basePtr))
{
//基类指针实际指向派生类对象才转换成功,并且derivedPtr将初始化为basePtr所指的Derived对象。
}
else
{
//否则,转换失败,转换结果为0,derivedPtr置为0.
}
*转换后的指针可以调用派生类的非虚函数,而虚函数机制则不能。