怎么在c++中定义RTTI的类型进行转换

  介绍

这篇文章给大家介绍怎么在c++中定义RTTI的类型进行转换,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

前言

RTTI是运行时类型信息的缩写,从字面上来理解就是执行时期的类型信息,其重要作用就是动态判别执行时期的类型。

为什么会有RTTI ?

c++是一种静态类型语言,其数据类型是在编译期就确定的,不能在运行时更改。然而由于面向对象程序设计中多态性的要求,c++中的指针或引用(参考)本身的类型,可能与它实际代表(指向或引用)的类型并不一致。有时我们需要将一个多态指针转换为其实际指向对象的类型,就需要知道运行时的类型信息,这就产生了运行时类型识别的要求。

实事求是地讲,RTTI是有用的。但因为一些理论上及方法论上的原因,它破坏了面向对象的纯洁性。

首先,它破坏了抽象,使一些本来不应该被使用的方法和属性被不正确地使用。

其次,因为运行时类型的不确定性,它把程序变得更脆弱。

第三点,也是最重要的一点,它使程序缺乏扩展性。当加入了一个新的类型时,你也许需要仔细阅读你的dynamic_cast的代码,必要时改动它们,以保证这个新的类型的加入不会导致问题。而在这个过程中,编译器将不会给你任何帮助。

总的来说,RTTI因为它的方法论上的一些缺点,它必须被非常谨慎地使用。今天面向对象语言的类型系统中的很多东西就是产生于避免RTTI的各种努力。

首先我们来个例子感受一下:

# include   # include   using  namespace 性传播疾病;      class 基地   {   公众:   ,virtual  void  funcA (), {, cout  & lt; & lt;,“Base", & lt; & lt;, endl;,}   };      class  Derived : public 基地   {   公众:   ,virtual  void  funcB (), {, cout  & lt; & lt;,“Derived", & lt; & lt;, endl;,}   };      void  funcC(基地*,p)   {   ,派生* dp =, dynamic_cast<派生*祝辞(p);   ,if  (dp  !=, NULL), {   dp→才能funcB ();   ,}   ,else  {   p→才能funcA ();   ,}   };      void  funcD(基地*,p)   {   ,派生* dp =,空;   ,if (类型id (* p),==,类型id(派生))   ,{   dp 才能=,static_cast<派生*祝辞(p);   dp→才能funcB ();   ,}   ,else  {   p→才能funcA ();   ,}   }      int 主要(int 命令行参数个数,char 常量*,argv [])   {   ,基地* p =, new 派生;   ,cout  & lt; & lt;类型id (p) . name (), & lt; & lt;, endl;   ,cout  & lt; & lt;类型id (* p) . name (), & lt; & lt;, endl;   ,funcD (p);   ,funcC (p);   ,delete  p;      ,基地* dp =, new 基础;   ,funcC (dp);   ,funcD (dp);   ,delete  dp;   ,return  0;   }

funcC是用dynamic_cast类型转换是否成功来识别类型的,dynamic_cast操作符将基类类型对象的引用或指针转化为同一继承层次中的其他类型的引用或指针。

<李>

如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。

<李>

如果转换到指针类型的dynamic_cast失败,则dynamic_cast的结果是NULL值;

<李>

如果转换到引用类型的dynamic_cast失败,则抛出一个bad_cast类型的异常

funcD是用类型id判断基类地址是否一致的办法来识别类型的。

类型id

下面我们具体说说类型id

类型id是c++的关键字之一,等同于sizeof这类operator. typeid操作符的返回结果是名为type_info的标准库类型的对象的引用,在头文件typeinfo中定义。有两种形式:

<李>

类型id(类型)

<李>

类型id(表达式)

表达式的类型是类类型,且至少含有一个虚函数,则类型id操作符返回表达式的动态类型,需要在运行时计算,否则返回表达式的静态类型,在编译时就可以计算。

c++标准规定了其实现必须提供如下四种操作:

<李>

t1==t2:如果两个对象t1和t2类型相同,则返回真的,否则返回假

<李>

t1 !=t2:如果两个对象t1和t2类型不同,则返回真的,否则返回假

<李>

t.name():返回类型的C风格的字符串,类型名字用系统相关的方法产生

<李>

t1.before (t2):返回指出t1是否出现在t2之前的bool值

怎么在c++中定义RTTI的类型进行转换