RTTI

来源:互联网 发布:zepto.js swipeleft 编辑:程序博客网 时间:2024/06/05 11:38

--------------siwuxie095

  

  

  

  

  

  

  

这里介绍一个高大上的名词:RTTI

  

  

  

  

  

  

RTTI

  

  

RTTI,即 Run-TimeTypeIdentification

  

  

  

  

C++ 中,也称为 运行时类型识别

  

  

  

  

RTTI 的体现方式:

  

  

  

  

看如下实例:

  

定义一个Flyable 类,其中有两个纯虚函数:takeoff() 和 land()

  

  

  

  

再定义一个Bird 类,它 public 的继承了 Flyable 类,并实现了 takeoff()

和 land(),并拥有自己独有的函数:foraging(),即 觅食

  

  

  

  

再定义一个Plane 类,它 public 的继承了 Flyable 类,并实现了 takeoff()

和 land(),并拥有自己独有的函数:carry(),即 运输

  

  

  

  

在使用时:

  

  

  

假设有这样一个函数:doSomething(),其参数是 Flyable 的一个

指针,在函数体中可以使用obj 去调用 takeoff() 和 land()

  

  

再设想一下,如果能够对传入的指针再做进一步的判断,即:

  

1)如果判断它是一个Bird 的对象指针,就能使用指针去调用 觅食 的函数

  

2)如果判断它是一个Plane 的对象指针,就能使用指针去调用 运输 的函数

  

  

  

如果想要做到上述判断,就要使用RTTI 运行时类型识别

  

  

  

typeid(*obj).name() 可以获得当前 obj 指针指向的实际的对象类型

  

cout 可以将其打印出来,再通过 if 语句进行比对,比对完成后,

就可以将obj 通过 dynamic_cast 的方式将其转化成为 bird 的指针

  

转化时要注意:dynamic_cast 后面跟两个尖括号,中间写上要转化

的目标类型

  

  

  

总结:

  

关于 dynamic_cast 的注意事项:

  

  

  

1)只能应用与指针和引用的转换,即只能转化为某一个类型的

指针某一个类型的引用,而不能是某类型本身

  

2)要转化的类型中必须包含虚函数,如果没有虚函数,转换就会失败

  

3)如果转换成功,返回子类的地址,如果转换失败,返回NULL

  

  

  

关于 typeid 的注意事项:

  

  

  

1)typeid 返回一个 type_info 的对象引用

  

2)如果想通过基类的指针指向派生类的数据类型,基类

就必须要带有虚函数,否则,在使用typeid 时,就只能返

回定义时所使用的数据类型

  

3)typeid 只能获取对象的实际类型,即便这个类含有虚

函数,也只能判断当前对象是基类还是派生类,而不能判断

当前指针是基类还是派生类

  

  

  

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

  

#include <iostream>

using namespace std;

  

  

//接口类

class Flyable

{

public:

virtualvoid takeoff() =0;

virtualvoid land() =0;

};

  

#endif

  

  

  

Bird.h:

  

#ifndef BIRD_H

#define BIRD_H

  

#include"Flyable.h"

  

class Bird:public Flyable

{

public:

void foraging();

virtualvoid takeoff();

virtualvoid 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();

virtualvoid takeoff();

virtualvoid 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 <stdlib.h>

#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");

return0;

}

  

void doSomething(Flyable *obj)

{

//通过typeid获取到type_info的一个引用

//通过引用调用name()成员函数返回数据类型

//

//这里打印的是数据类型传入的不是obj指针而是对象*obj

cout <<typeid(*obj).name() << endl;

  

obj->takeoff();

 

//两个type_info对象的比对运算符重载

if (typeid(*obj) ==typeid(Bird))

{

//转化为Bird的指针

Bird *bird =dynamic_cast<Bird *>(obj);

bird->foraging();

}

if (typeid(*obj)==typeid(Plane))

{

Plane *plane =dynamic_cast<Plane *>(obj);

plane->carry();

}

obj->land();

}

  

//RTTI: Run-Time Type Identification运行时类型识别

//RTTI的体现方式:typeid dynamic_cast

//

//dynamic_cast后面跟2个尖括号 <> dynamic<>里面填上要转化的目标类型

//

//dynamic_cast注意事项:

//1)只能应用于指针和引用的转换

//2)要转换的类型必须包含虚函数

//3)转换成功返回子类的地址,失败返回NULL

//

//typeid注意事项:

//1typeid返回一个type_info对象的引用

//2)如果想要通过基类的指针获得派生类的数据类型,基类必须带有虚函数

//3)只能获取对象的实际类型

//(判断当前对象属于基类还是派生类只能判断对象不能判断指针)

//

//关于type_info,如下:

//class type_info

//{

//public:

// //name()函数

// const char* name() const;

// //运算符重载

// bool operator==(const type_info& rhs) const;

// bool operator!=(const type_info& rhs) const;

// int before(const type_info& rhs) const;

// virtual ~type_info();

//private:

// ....

//};

  

  

运行一览:

  

  

  

  

  

  

  

  

  

  

  

【made by siwuxie095】

0 0
原创粉丝点击