C++ RTTI
来源:互联网 发布:淘宝网之女款坡跟短靴 编辑:程序博客网 时间:2024/05/29 12:17
一,RTTI(Runtime Type Identification)的用途
假设有一个类层次结构,其中的类都是从同一个基类派生而来的,则可以让基类指针指向其中任何一个类的对象。这样便可以调用这样一个函数:在处理一些信息后,选择一个类,并创建这种类型的对象,然后返回它的地址,而该地址可以被赋为基类指针。如何知道指针指向的是哪种类型的对象呢?
在回答这个问题之前,先考虑为何要知道类型。可能希望调用类方法的正确版本,在这种情况下,这要该函数是类层次结构中所有成员都拥有的虚函数,则并不真正需要知道对象的类型。但派生类可能包含不是派生而来的方法,在这种情况下,只有某些类型的对象可以使用该方法。对于这种情况,RTTI提供了解决方案。
注意: 只能将RTTI用于包含虚函数的类层次结构,原因在于只有对于这种层次结构,才应该将派生类对象的地址赋给基类指针。
二,RTTI的工作原理
C++ 有三个支持RTTI的元素
a,dynamic_cast
1,dynamic_cast的作用与语法
dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针,用来执行"安全向下类型转换",也就是用来决定某对象是否属于某继承体系中的某个类。通常,想知道类型的原因在于:知道类型后,就可以知道调用特定的方法是否安全。例如,有下面的类继承体系:
class Grand{...};class Superb : public Grand{...};class Magnificent : public Superb{...};首先,看下dynamic_cast的语法。该运算符的用法如下,其中pg指向某个对象:
Superb *pb = dynamic_cast<Superb *>(pg);这提出了这样的问题:指针pg的类型是否可以安全地转换为Superb *?如果可以,运算符将返回对象的地址,否则返回一个空指针。通常,如果指向的对象(*pt)的类型为Type或者是从Type直接或间接派生而来的类型,则下面的表达式将指针(*pt)转换为Type类型的指针。
dynamic_cast<Type *>(pt);
2,使用dynamic_cast来检查是否可以进行安全类型转换
class Grand{public: virtual void speak(){ cout<<"Grand Speak"<<endl; }};class Superb : public Grand{public: virtual void speak(){ cout<<"Superb Speak"<<endl; } virtual void say(){ cout<<"Superb say"<<endl; }};class Magnificent : public Superb{public: void speak(){ cout<<"Magnificent Speak"<<endl; } void say(){ cout<<"Magnificent say"<<endl; }};
上面定义了三个类,Grand、Superb、Magnificent。Grand类定义了虚函数speak(),而其它的类都继承了该虚函数。Superb类定义了一个虚函数say(),而Magnificent也重新定义了它。程序定义了getOne()函数,该函数随机创建这三种类中某个类的对象。然后将对象的地址作为Grand*指针返回,循环将返回的指针赋给Grand*变量pg,然后使用pg调用speak()函数。因为这个函数是虚函数,所以代码能够正确调用指向的对象的speak()版本。如下:
Grand *pg;for(int i = 0; i < 5; i ++){ pg = getOne(); pg->speak();}但是不能用相同的方式来调用say()函数,因为Grand类没有定义say()函数。然而,可以使用dynamic_cast运算符来检测是否可以安全地将pg转换为Superb类型指针。如果pg指向的对象的实际类型为Superb或Magnificent,则可以安全类型转换。在这两种情况下,都可以安全调用say()函数。
Grand *pg;Superb *ps;for(int i = 0; i < 5; i ++){ pg = getOne(); if(ps = dynamic_cast<Superb *>(pg)){ ps->say(); }}
b,typeid
1,typeid运算符的语法与作用
typeid运算符能够确定两个对象是否是同种类型。它接受两个参数,一是类名,二是结果为对象的表达式。typeid运算符返回一个type_info对象的引用,其中type_info是在头文件typeinfo中定义的一个类。type_info类重载了==和!=运算符,以便于使用这些运算符对类型进行比较。
2,typeid运算符的使用
typeid(Magnificent) == typeid(*pg);如果pg指向的是一个Magnificent对象,则上面表达式的结果为true,否则为false。如果pg是一个空指针,程序将引发bad_typeid异常。
c,type_info
1,type_info的语法与作用
type_info的实现随厂商而异,但包含一个name()成员,该函数返回一个随实现而异的字符串,通常是类的名称。
2,type_info的使用
cout<<typeid(*pg).name()<<endl;
- 【C/C++】RTTI
- ?[C++_10]RTTI
- <C++> RTTI机制
- C++RTTI小总结
- C++RTTI强制转型
- C++RTTI和反射机制
- RTTI
- RTTI
- rtti
- RTTI
- RTTI
- RTTI
- RTTI
- RTTI
- RTTI
- RTTI
- RTTI
- RTTI
- easyui datagrid 数据加载到另一datagrid
- 使用搜索引擎
- java比较两段json不同工具类(两个同一类型的java对象比较也推荐转成JSON再进行比较)
- Samba文件共享
- 深入理解ConcurrentHashMap之源码分析(JDK8版本)
- C++ RTTI
- openssh-server,sshd服务
- 链表的有序集合(java)
- RecyclerView使用大全
- json对象转map方法之一,通过遍历json对象的所有key,取出value放入map
- C++ static_cast、dynamic_cast、const_cast和reinterpret_cast的总结辨析
- STM32F429串口无法升级程序解决方案
- 网络编程_客户端读取文本文件服务器控制台输出
- 生成字母和数字组合的随机数