运行时类型识别,根据基类指针或引用检索指针或引用所指对象的实际类型函数
要使用RTTI,要求基类中具备虚函数spa
两种方法支持RTTI:指针
typeid操做符code
dynamic_cast操做符对象
当须要经过基类指针或引用调用不是基类组成部分的派生类成员,就须要将基类指针或引用转换为派生类的指针或引用;固然也能够经过虚函数的方式,可是某些状况下是不可能使用虚函数的,好比静态成员函数;见下:继承
/* * main.cc * * Created on: 2014年1月15日 * Author: root */ #include <stdio.h> class A{ public: static void print(){ printf("A\n"); } virtual ~A(){ ; } /* 基类必需要用虚函数才能使用RTTI */ }; class B:public A{ public: static void print(){ printf("B\n"); } virtual ~B(){ ; } }; int main(int argc,char *argv[]){ A *a=new B; a->print(); /* 若是要调用B版本的print;此时不可能经过虚函数 * 因此必须使用动态类型转换,即dynamic_cast操做符 */ /* 此时b的做用域为if块与if匹配的else块中 */ if(B *b=dynamic_cast<B*>(a)) b->print(); else a->print(); delete a; return 0; }
dynamic_cast<派生类指针或引用>(基类指针或引用),将基类指针或引用转换为同一继承层次中派生类的指针或引用;作用域
dynamic_cast会进行运行时检查,若是基类指针或引用所指对象的实际类型不是'<派生类指针或引用>'类型,如:字符串
class A{ virtual ~A(){} }; class B:public A{}; class C:public A{}; int main(int argc,char *argv[]){ A *a=new B; dynamic_cast<C*>(a); /* 此时就会转换失败 */ delete a; return 0; }
对于 dynamic_cast<派生类指针>(基类指针):io
转换失败的话,返回0;ast
对于 dynamic_cast<派生类引用>(基类引用):
因为不存在空引用,因此转换失败的话,抛出bad_cast异常;
typeid(表达式),返回type_info类型,type_info类是对表达式的类型的一个包装,若是有虚函数支持的话,则会返回表达式的运行时实际类型;type_info支持如下操做:
/* 必须包含 <typeinfo> 头文件才能使用 */ bool operator==(const type_info &__type); bool operator!=(const type_info &__type); /* 判断两个类型是否相等 */ const char *name()const; /* 返回类型的字符串表示 */
/* * main.cc * * Created on: 2014年1月15日 * Author: root */ #include <stdio.h> #include <typeinfo> class A{ public: static void print(){ printf("A\n"); } virtual ~A(){ ; } }; class B:public A{ public: static void print(){ printf("B\n"); } virtual ~B(){ ; } }; int main(int argc,char *argv[]){ B b; A *a=&b; if(typeid(*a) ==typeid(B) ) printf("B: %s\n",typeid(*a).name()); else printf("AA\n"); return 0; }