首页 > 代码库 > C++中3种多态实现机制之RTTI

C++中3种多态实现机制之RTTI

多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象的语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将基类设置成为和一个或更多的他的子类相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息。它提供了运行时确定对象类型的方法。本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI;

本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和 dynamic_cast。

首先让我们来设计几个层次类:(这里尽可能的简单)

基类:

class Human

{

};

class Chinese : public Human

{

};

class Japanese : public Human

{

};

/////////////////////////////////////////////////////////

使用场景:有个函数

void Kill(Human *pHuman)

{

  if(typeid(*pHuman) == typeid(Japanese))

  {

    //kill

  }

  else if(typeid(*pHuman) == typeid(Chinese))

  {

    // not kill

  }

}

这样在传入 Japanese 的时候就会Kill了。

 

typeid的name函数用于查看对象类型

例如:Chinese human;

cout << human is << typeid(human).name() << endl;

会输出: human is Class Chinese

 

dynamic_cast,这个运算符用于多态编程中保证在运行时发生正确的转换(即编译器无法验证是否发生正确的转换)。dynamic_cast 常用于从多态编程基类指针向派生类指针的向下类型转换。它有两个参数:一个是类型名;另一个是多态对象的指针或引用。其功能是在运行时将对象强制转换为目标类型并返回布尔型结果。

Kill 第二版

void Kill(Human *pHuman)

{

  if(dynamic_cast<Japanese*>(pHuman))

  {

    //kill

  }

  else

  {

    // not kill

  }

}

///////////////////////////////////////////

虽然使用 dynamic_cast 确实很好地解决了我们的问题,但也需要我们付出代价,那就是与 typeid 相比,dynamic_cast 不是一个常量时间的操作。为了确定是否能完成强制类型转换,dynamic_cast`必须在运行时进行一些转换细节操作。因此在使用 dynamic_cast 操作时,应该权衡对性能的影响.

 

RTTI具体使用场景:

假设你正在开发一个基于图形用户界面(GUI)的文件管理器,每个文件都可以以图标方式显示。当鼠标移到图标上并单击右键时,文件管理器打开一个菜单,每个文件除了共同的菜单项,不同的文件类型还有不同的菜单项。如:共同的菜单项有“打开”“拷贝”、和“粘贴”,此外,还有一些针对特殊文件的专门操作。比如,文本文件会有“编辑”操作,而多媒体文件则会有“播放”菜单。为了使用 RTTI 来动态定制菜单,文件管理器必须侦测每个文件的动态类型。利用 运算符 typeid 可以获取与某个对象关联的运行时类型信息。typeid 有一个参数,传递对象或类型名。因此,为了确定 x 的动态类型是不是Y,可以用表达式:typeid(x) == typeid(Y)实现:#include <typeinfo> // typeid 需要的头文件
void menu::build(const File * pfile)
{
if (typeid(*pfile)==typeid(TextFile))
{
add_option("edit");
}
else if (typeid(*pfile)==typeid(MediaFile))
{
add_option("play");
}
}

 

 

 

 ----------------努力向学 蔚为国用-----------------

C++中3种多态实现机制之RTTI