RTTI定义:
RTTI:Run Time Type Identification,运行时类型识别:指程序能够使用基类的指针或引用来检索其所指对象的实际派生类型
使用方式:
C++中有几个个操作符提供RTTI:
typeid操作符:返回指针或引用所指对象的实际类型dynamic_cast操作符:将基类类型的指针或引用安全地转换为派生类型的指针和引用type_info:很少直接使用,但是需要了解一下,type_info的定义是由编译器定的,但是共同的是它包含一个name()函数注:这些操作符只为带有一个或多个虚函数的类返回动态类型信息—-即在运行时执行RTTI操作符,对于其他类型则返回静态类型的信息—即在编译时计算RTTI操作符
详细介绍:
typeid的使用:
#include <iostream>#include <typeinfo> //添加的头文件using namespace std;class Base1{ };class Derive1 : public Base1{ };class Base2{ virtual void fun( void ) { }};class Derive2 : public Base2{ };class Derive22 : public Base2{ };int main( void ){ // sample1: cout << typeid(1.1f).name() << endl;// 输出float // sample2: Derive1 d1; Base1& b1 = d1; cout << typeid(b1).name() << endl; // 输出"class Base1",因为Derive1和Base1之间没有多态性 // sample3: Derive2 d2; Base2& b2 = d2; cout << typeid(b2).name() << endl; // 输出"class Derive2",因为Derive1和Base1之间有了多态性 // sample4: Derive2 *d22; Base2 *b22; cout<<boolalpha<<(typeid(*d22)==typeid(*b22))<<endl; //输出true,typeid(*d22)==typeid(Base2):输出false // sample5: Base1 *b=new Derive1(); cout<<typeid(b).name()<<endl; //输出class Base1 * cout<<typeid(*b).name()<endl; //输出class Derive1 return 0;}dynamic_cast的使用:
#include <iostream>#include <typeinfo>using namespace std;class Base2{ virtual void fun( void ) { }};class Derive2 : public Base2{ };class Derive22 : public Base2{ };//指针强制转化失败后可以比较指针是否为零,而引用却没办法,所以引用制转化失败后抛出异常// 指针转换:Derive2 d2;Base2& b2 = d2;Derive2* pb1 = dynamic_cast<Derive2*>(&b2);cout << boolalpha << (0!=pb1) << endl; // 输出"true",因为b2本身就是Derive2Derive22* pb2 = dynamic_cast<Derive22*>(&b2);cout << boolalpha << (0!=pb2) << endl; // 输出"false",因为b2本身就是Derive2// 引用转化:try { Derive2& rb1 = dynamic_cast<Derive2&>(b2); cout << "true" << endl;} catch( bad_cast ){ cout << "false" << endl;}try { Derive22& rb2 = dynamic_cast<Derive22&>(b2); cout << "true" << endl;} catch( ... ) {// 应该是 bad_cast,但不知道为什么在VC++6.0中却不行 cout << "false" << endl;}typeid(pa)
返回的是指针类型,如果要返回对象的类型需要使用引用或者对象作为参数传递给typeid
dynamic_cast
是个运行时操作,但是它完全依赖虚函数表,如果某个两个类之间有继承关系,但是没有虚函数,那么dynamic_cast不能进行转化,也不能从void *都某个具体类的转化,会报告编译时错误
注意事项总结:
dynamic_cast的注意事项:
1.只能用于指针和引用之间的转换2.要转换的类型中必须包含虚函数3.转换成功返回子类的地址,失败返回NULLtypeid的注意事项:
1.type_id返回type_info对象的引用2.如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数3.只能获得对象的实际类型新闻热点
疑难解答
图片精选