一、前言
RTTI(运行时类型信息)是被现代高级编程语言所普遍支持的特性之一,如C#中的“a is A”、JAVA中的“a instanceof A”都属于RTTI的范畴。然而Symbian OS C++并不支持这个特性,这导致由Win32、JAVA转向Symbian的开发人员或者代码的移植都带来很大的不便,本文将解决这个问题。
二、什么是RTTI
RTTI指的是“运行时类型识别(Run-Time Type Identification)”或者“运行时类型信息(Run-Time Type Information)”,程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
随着应用场合之不同﹐所需支持的RTTI范围也不同。最单纯的RTTI包括:
类识别(class identification)──包括类名称或ID。
继承关系(inheritance relationship)──支持执行时期的“往下变换类型”(downward casting),亦即动态变换类型(dynamic casting) 。
三、Symbian OS中的RTTI
由于Symbian系统以及它运行的硬件环境的限制,造成Symbian系统编程不能完全像一般C++程序设计随心所欲,Symbian OS C++并不提供对RTTI的支持。所以,标准C++中的dynamic_cast<>、typeid()及type_info都是不被支持的。
四、移植MFC代码实现RTTI
VC++编译器从4.0版才开始支持RTTI,但MFC 4.x 并未使用编译器的能力完成其对RTTI 的支持。MFC 有自己一套沿用已久的办法(从1.0 版就开始了)。在此,我们借用MFC中实现RTTI的代码,来完成对Symbian OS C++ RTTI的支持。
关于MFC中RTTI的实现原理,侯捷的《深入浅出MFC》里已经有详细的阐述,基本原理是使用几个特殊的宏手动的在编译期间确定一个对象继承关系链表,在此不再说明具体原理。
我们移植的是VC++ 9.0中MFC实现RTTI的代码,不使用侯捷在《深入浅出MFC》中所提供的模拟代码。因为侯捷的代码中存在非常多的“可写的静态数据”,将不能在Symbian DLL或者2nd版的APP中使用。然而,VC++ 9.0中的MFC代码没有存在以上问题,所以可以再任何Symbian代码中使用。
压缩包内包含两个文件:Rtti.h、Rtti.cpp。将这两个文件加入工程后,着手设计实现RTTI的类:
1、类的声明:
Rtti.h头文件中的CRttiBase是拥有RTTI特性的基础类,此类相当于MFC中的CObject,它继承自CBase,所有要实现RTTI特性的类都要从此类派生,并且在声明加入一个特殊的宏:
1 class CMyClass : public CRttiBase
2 {
3 DECLARE_DYNAMIC(CMyClass)
4 ...
5 };
注意:宏DECLARE_DYNAMIC中的第一个参数为当前类的类名:CMyClass。
声明第二个类继承自CMyClass,同样的,要加上DECLARE_DYNAMIC宏:
1 class CMyClass1 : public CMyClass
2 {
3 DECLARE_DYNAMIC(CMyClass1)
4 ...
5 };
注意:实现RTTI的子类继承自父类,而父类必须继承自CRttiBase。