本文共 3370 字,大约阅读时间需要 11 分钟。
RTTI,即 Run-Time Type Identification
在C++ 中,也称为 运行时类型识别
定义一个Flyable 类,其中有两个纯虚函数:takeoff() 和 land()
再设想一下,如果能够对传入的指针再做进一步的判断,即:
如果判断它是一个Bird 的对象指针,就能使用指针去调用 觅食 的函数
如果判断它是一个Plane 的对象指针,就能使用指针去调用 运输 的函数
如果想要做到上述判断,就要使用RTTI 运行时类型识别
转化时要注意:dynamic_cast 后面跟两个尖括号,中间写上要转化的目标类型。
总结:
关于 dynamic_cast 的注意事项:
只能应用与指针和引用的转换,即只能转化为某一个类型的指针或某一个类型的引用,而不能是某类型本身
要转化的类型中必须包含虚函数,如果没有虚函数,转换就会失败
如果转换成功,返回子类的地址,如果转换失败,返回NULL
关于 typeid 的注意事项:
typeid 返回一个 type_info 的对象引用
如果想通过基类的指针指向派生类的数据类型,基类就必须要带有虚函数,否则,在使用typeid 时,就只能返回定义时所使用的数据类型
type_info 中的内容:
class type_info{private: type_info(const type_info&); type_info& operator=(const type_info&);//type_info类的复制构造函数和赋值运算符是私有的。public: virtual ~type_info();//析构函数 bool operator==(const type_info&)const;//在type_info类中重载了==运算符,该运算符可以比较两个对象的类型是否相等。 bool operator!=(const type_info&)const;//重载的!=运算符,以比较两个对象的类型是否不相等 const char* name()const;//使用得较多的成员函数name,该函数返回对象的类型的名字。前面使用的typeid(a).name()就调用了该成员函数 bool before(const type_info&);};
在上例中,typeid(*obj) 获取到的就是一个 type_info 的引用,通过该引用就能调用 type_info 中的 name() 函数。
type_info 中的 bool operator==(const type_info& rhs) const; 即运算符重载,通过它就可以进行两个type_info 对象的比对。
程序:
//Flyable.h#ifndef FLYABLE_H#define FLYABLE_H#includeusing namespace std;//接口类class Flyable{public: virtual void takeoff() = 0; virtual void land() = 0;};#endif
//Bird.h#ifndef BIRD_H#define BIRD_H#include"Flyable.h"class Bird:public Flyable{public: void foraging(); virtual void takeoff(); virtual void land();};#endif
//Bird.cpp#include"Bird.h"void Bird::foraging(){ cout << "Bird--foraging" << endl;}void Bird::takeoff(){ cout << "Bird--takeoff" << endl;}void Bird::land(){ cout << "Bird--land" << endl;}
//Plane.h#ifndef PLANE_H#define PLANE_H#include"Flyable.h"class Plane:public Flyable{public: void carry(); virtual void takeoff(); virtual void land();};#endif
//Plane.cpp#include"Plane.h"void Plane::carry(){ cout << "Plane--carry" << endl;}void Plane::takeoff(){ cout << "Plane--takeoff" << endl;}void Plane::land(){ cout << "Plane--land" << endl;}
//main.cpp#include"Bird.h"#include"Plane.h"void doSomething(Flyable *obj);int main(void){ Bird b; Plane p; doSomething(&b); cout << endl; doSomething(&p); //对typeid的验证 /*cout << endl; int i = 0; cout << typeid(i).name() << endl; Flyable *t = new Bird(); cout << typeid(t).name() << endl; cout << typeid(*t).name() << endl;*/ system("pause"); return 0;}void doSomething(Flyable *obj){ //这里打印的是数据类型, 传入的不是obj指针而是对象*obj cout << typeid(*obj).name() << endl; obj->takeoff(); //两个type_info对象的比对运算符重载 if (typeid(*obj) == typeid(Bird)) { //转化为Bird的指针 Bird *bird = dynamic_cast(obj); bird->foraging(); } if (typeid(*obj)==typeid(Plane)) { Plane *plane = dynamic_cast (obj); plane->carry(); } obj->land();}
运行一览:
此文章转载自: