运行时类型识别(RTTI)
RTTI英文全称为:Run-Time Type Identification(运行时类型识别)
首先介绍两个东西:typeid和dynamic_cast
typeid:c++中该函数用于获知一个变量的具体类型。
dynamic_cast:主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
具体用法如下:
typeid(
expression
).name(): 该运算符返回expression的类型名
dynamic_cast < type-id > ( expression ):该运算符把expression转换成type-id类型的对象。
dynamic_cast注意事项:
1.只能应用于指针和引用的转换。
2.要转换的类型中必须包含虚函数。
3.转换成功返回子类的地址,失败返回NULL。
typeid注意事项:
1.type_id返回一个type_info对象的引用。
2.如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数。
3.只能获取对象的实际类型。
通过下面一段代码来了解:
/*接口类*/
#ifndef FLYABLE_H
#define FLYABLE_H
class Flyable
{
public:
virtual void takeoff()=0; /*只有纯虚函数*/
virtual void land()=0;
};
#endif
/*Bird.h*/
#ifndef BIRD_H
#define BIRD_H
#include"Flyable.h"
#include<string>
using namespace std;
class Bird :public Flyable
{
public:
void foraging();
virtual void takeoff();
virtual void land();
};
#endif
/*Bird.cpp*/
#include<iostream>
#include"Bird.h"
using namespace std;
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"
using namespace std;
class Plane :public Flyable
{
public:
void carry();
virtual void takeoff();
virtual void land();
};
#endif
/*Plane.cpp*/
#include<iostream>
using namespace std;
#include"Plane.h"
void Plane::carry()
{
cout << "Plane--carry" << endl;
}
void Plane::takeoff()
{
cout << "Plane--takeoff" << endl;
}
void Plane::land()
{
/*demo.cpp*/
#include<iostream>
#include"Flyable.h"
#include"Bird.h"
#include"Plane.h"
using namespace std;
void doSomething(Flyable *obj)
{
cout << typeid(*obj).name() << endl;
obj->takeoff();
if (typeid(*obj)==typeid(Bird))
{
Bird *bird = dynamic_cast<Bird *>(obj);
bird->foraging();
}
if (typeid(*obj)==typeid(Plane))
{
Plane *plane = dynamic_cast<Plane *>(obj);
plane->carry();
}
obj->land();
}
int main(void)
{
Plane b;
doSomething(&b);
system("pause");
return 0;
}
运行结果:
若修改为以下代码:
int main(void)
{
Bird b;
doSomething(&b);
system("pause");
return 0;
}
则运行结果为: