RTTI(Runtime Type Identification/Information)
如果要实现运行时的RTTI,必须在类中加入一些唯一识别信息,静态成员变量则提供了这样一种方法。对于类而言,静态成员的地址信息是唯一确定的,这样就可以设计一种实现RTTI的方法。
1. typeid and dynamic_cast
标准C++中定义了type_info这个类用来表示对象的类型信息,同时增加了typeid运算符来取得类型信息。typeid()以一个对象或者类型名作为参数,返回一个匹配的const type_info对象来表明对象的确切类型。type_info常用的3个成员函数为operator ==()、operator !=()和name(),请参考标准头文件<typeinfo>。
对于“Class obj;”而言,typeid(obj)返回一个type_info对象的引用,而typeid(Class)返回一个type_info对象。
在多态类型(即带virtual函数的类)中,typeid()可以实现类似virtual函数动态绑定的功能,此时可以将typeid()看作是一个virtual函数。
除多态类型外,typeid()同样可以用来获得非多态类型对象和基本数据类型对象的类型信息。
注:typeid只能取得类型信息,而无法检查类间的继承关系,虽然它有类似虚函数动态绑定的功能。typeid的功能和下面讲述的RUNTIME_CLASS宏、GetRuntimeClass()函数在原理上类似。
如果要判断类之间的继承关系,则需要用到dynamic_cast<>这个算符。dynamic_cast实现类似下面提到的IsDerivedFrom()这个函数的功能。
2. RTTI in MFC
MFC中的RTTI实现方法和标准C++中应该是类似的,但MFC比C++标准中引入RTTI的时间要早,所以MFC提供了自己的一套方式。这里有一个模拟,比MFC中提供的要简单一些。(暂不提供一步步的设计过程,以后再加。)
补充:CRuntimeClass只是用来表示类型信息,而不是运行时类型信息(RTTI),将类继承关系中的各个CRuntimeClass对象组织起来,并使用IsDerivedFrom函数来判断继承关系,才是实现RTTI的核心所在。
两种实现方式的对比:
| 标准C++ | MFC |
类型信息结构 | type_info | CRuntimeClass |
取得类型信息 | typeid() | RUNTIME_CLASS() GetRuntimeClass() |
判断继承关系 | dynamic_cast<> | IsDerivedFrom() |