Symbian编程总结-深入篇-RTTI的实现及原理说明

一、前言

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。

时间: 2024-08-03 15:51:16

Symbian编程总结-深入篇-RTTI的实现及原理说明的相关文章

Symbian编程总结-基础篇-集合与缓冲区(2)-验证RArray::Append

Symbian编程总结-基础篇-集合与缓冲区(2)-验证RArray::Append是否保存对象副本 一.验证栈对象会自动销毁 我们知道,在C++中,在函数中创建了栈对象,函数退出时,该栈对象会自动销毁(栈指针后移了,栈内存会被覆盖).如何验证这一点?我们需要在函数外定义一个整形变量,在函数内将该函数内获取了变量的地址,在函数调用完毕后,将地址还原成对象: TInt iAddr; /** * 将地址还原成描述符对象并显示出来 * @param aAddr 地址 */ LOCAL_C void P

Symbian编程总结-基础篇-活动对象正解(4)-异步函数的同步调用

在上一节里我们深入了解了活动对象.活动调度器及异步函数服务器的工作原理及运行机制,想必大家对活动对象的机制及体系结构的运用已经了如指掌.但是大家有没有觉得异步函数使用起来比较麻烦呢?难道非要使用活动对象,非得以"异步"的方式调用异步函数吗?这一节将为大家解决这个问题:异步函数的同步使用. 一.使用CActiveSchedulerWait类 在以前的文章"Symbian编程总结-界面篇-打开jpeg/gif/png图像"里我们已经看到了CActiveScheduler

Symbian编程总结-基础篇-动态缓冲区(1)-回顾HBufC

当数据尺寸在编译期不固定,而在运行期有可能要扩展到很大尺寸时,动态缓冲区在保存二进制数据方面显得非常有用.我们可以使用C++数组保存二进制数据,然后调用类似于memcpy的函数去动态的改变数组所占用空间的大小:我们还能够使用HBufC描述符,获取其可修改的描述符向其写入数据,然后调用ReAlloc方法扩展数组.以上两点方法可行,但是不好,因为我们得自己管理内存的分配.Symbian C++考虑到了这一点,于是引入了动态缓冲区的概念. 基于堆的缓冲描述符HBufC的前缀H显然不符合Symbian

Symbian编程总结-深入篇-瘦模板正解

C++的模板对于那些可以被多种类型重用的代码是非常有用的,如:Symbian C++中的泛型集合RArray和RPointerArray就是使用的模板来实现的.但是,使用普通C++模板会带来代码尺寸大大增加的问题.本文将分为"C++模板基础"."TBuf分析"."瘦模板"三个部分,逐步深入讲解Symbian C++瘦模板的概念和使用方法. 一.C++模板基础 在这一部分中不会详细的介绍C++的模板,只会已不同的代码的形式介绍C++模板的几种不同的

Symbian编程总结-基础篇-描述符(1)-描述符简介

一.强化印象 在学习描述符之前,首先要理解Symbian中描述符的作用.在Symbian中,没有提供专门用来处理字符串的类,它把字符串和二进制缓冲区看成是同一类数据,有一套专门的类去管理,这一套类的类关系图层次结构如下图所示: 图一. 描述符类的层次关系 上图所示的类统称为"描述符",Symbian用"描述符"来管理字符串,其中,TDesC.TDes.TBufCBase为抽象类. 我们首先来举一个简单的例子,来强化我们对描述符的理解.如果我们由一个字符串"

Symbian编程总结-基础篇-类类型

原文出自:http://discussion.forum.nokia.com/forum/showthread.php?t=68969 译自Developer Library » Symbian OS Guide » Essential idioms » Class types 概要 Symbian OS上的应用程序使用4种常用的类,它们是: 以T开头的值类,这种类不拥有任何外部对象,只是通过指针直接引用或通过句柄间接引用外部对象. 以C开头的基于堆分配的类,这种类全部是从CBase派生过来的.

Symbian编程总结-基础篇-集合与缓冲区(1)-RArray和RPointerArray

Symbian OS不支持STL,主要原因是因为STL覆盖的面太广,不适合在内存受限的设备上使用. 在这里我们首先学习RArray模板类.如果您有java或者.net方面的经验,Symbian中的RArray和RPointerArray类似于java中的Vector<>或.net中的List<>. 注意事项: RArray和RPointerArray都是基于模板的 RArray的模板参数应该为R类或T类,而RPointerArray的模板参数可以是任意类型 RArray是固定长度对

Symbian编程总结-基础篇-活动对象正解(1)-理解活动对象

Symbian OS中的活动对象的使用无疑是最基础的.最频繁的.最重要的.什么是活动对象呢? 大家学习一个新的事物时,总是会将这个新的事物与自己认知的事物相比较,从而达到快速学习的目的.我开始学习Symbian的时候,我查看很多Symbian书籍.网上很多Symbian教程都将活动对象与多线程联系到一起,我也总是会把活动对象想象成一个线程.然而,经过了更深入的接触,我发现并不像我想象的那样. 现在,我在此向你保证:活动对象和多线程没有任何关系!不要拿平时做多线程的思想去理解活动对象! 活动对象可

Symbian编程总结-基础篇-描述符(2)-TDesC8与TDesC16之间的互转

1.使用Copy _LIT8(KTestStr, "This is a string"); TBufC8<50> buf(KTestStr); TBuf<100> newBuf; newBuf.Copy(buf); TBuf8<50> newBuf1; newBuf1.Copy(newBuf); 2.使用CCnvCharacterSetConverter类 _LIT8(KTestStr, "This is a String"n&q