【C/C++学习】之十四、RTTI

来源:互联网 发布:怎么发淘宝链接给别人 编辑:程序博客网 时间:2024/05/18 01:19

RTTI(Runtime TypeIdentification)

提供了运行时确定对象类型及转换指针或引用类型的方法。  有关内容包括类名称,数据成员名称与类型,函数名与类型等。

在大多数面向度地向专家传播自己设计理念时,都主张在设计和开发中使用虚拟成员函数而不是使用RTTI机制,但是再很多情况下虚拟成员函数无法克服本身的局限。每当涉及处理异类容器和根基类层次时,不可避免要对对象类型进行动态判断,也就是动态类型的侦测。在C++中提供了两个运算符typeid 和 dynamic_cast。

typeid   可以获取与某个对象关联的运行时类型信息。他返回的是type_info类型,该类型描述类型信息。

Typeid运算符用于获得一个类型或者对象的运行时信息,如下:

Typeid(type)

Typeid(object)

其中type可以是有虚函数的类类型,也可以是没有虚函数的类类型

1、  有虚函数

A *a = new B;

Typeid(a)==typeid(A*);和typeid(*a)==typeid(A)  都返回true                                                                                                                         

2、  无虚函数

A *a = new B;

Typeid(a)==typeid(A*)和typeid(*a)==typeid(A)都返回true

 

Typeid是在typeinfo.h头文件中,看下面代码

A *a = new B;

Cout << typeid(*a).name() <<endl;

Name函数可以获得指针a指向的对象类型,因为指针a指向的是一个B类型的对象,多以执行的时候会输出B。

如果a是NULL,那么会抛出bad_typeid异常。

 

Typeid和dynamic_cast区别:

1、  dynamic_cast运算符只能处理对象,而typeid运算符能够以类型和对象作为操作数,其中对象可以使基本类型,包括整形,浮点型,char等

2、  typeid()和dynamic_cast<>()函数都是在运行时才能获得类型信息,而不是在静态编译时获得。

3、  typeid()函数不是一个模板函数

4、  typeid()和dynamic_cast<>()函数接收基类指针或者引用,该指针或者引用可以指向一个派生类对象。

5、  typeid()函数返回类名,而dynamic_cast<>()函数被用来传递类名。

6、  使用typeid()函数能发现该对象的精确类型,但不能转换该指针,dynamic_cast<>()函数能转换该指针,但不能确定该对象的精确类型。

 

 

Dynamic_cast 

dynamic_cast

static_cast

const_cast

reinterpret_cast


执行dynamic_cast运算符需要额外的运行时间,为了避免性能损耗通常使用static_cast运算符。   虽然使用static_cast运算符在速度上优于dynamic_cast运算符,但是static_cast运算符在用于向下转型时可能存在危险并会导致错误。  如果一定要使用static_cast运算符,那么就要确保向下转型的安全性。

使用static_cast运算符并不能保证转型的有效性,static_cast运算符仅仅执行需要的指针运算,为了确保使用static_cast运算符进行向下转型是安全的,用户必须对每次要执行的转型都进行测试。如果使用dynamic_cast运算符就无需用户测试,因为dynamic_cast运算符执行失败时会返回空指针或抛出异常。


要注意的是:

默认情况下,编译器是关闭RTTI的,目的是消除性能上的开销,如果程序中使用了RTTI,那么编译前要进行启用RTTI。

 

 

 

最基本的RTTI包括:

1、  类识别:类名称或ID

2、  继承关系:支持运行时的向下转换,即动态转换

3、  对象结构:属性的类型、名称及其位置

4、  成员函数:函数的类型、名称及其参数类型等

5、  能获得类所实例化的各对象

 

RTTI常见的应用:   异常处理,动态转换,多个文件集成,对象IO

1、  异常处理:需要RTTI  例如类名称等

2、  动态转换:在类中,向下转换需要类继承的RTTI

3、  多个文件集成:当某个程序中的对象需要使用另一个程序中的对象时,在一般的C++程序中,常见的解决方法是在源代码中将需要的对象的类定义包含进来,在编译时将当前文件与其包含的文件集成,但又无法再次重新编译,因此只能依赖于RTTI。

4、  对象IO:C++将IO对象及与它相关的独享所属的类名称等RTTI内容完整的保存起来,读取对象时可依赖这些RTTI内容为对象分配内存空间。


2012/10/14

jofranks 于南昌

原创粉丝点击