Symbian系统开发教程2_第1页
Symbian系统开发教程2_第2页
Symbian系统开发教程2_第3页
Symbian系统开发教程2_第4页
Symbian系统开发教程2_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、:数据类型与语法作者:谢兴 HYPERLINK mailto:enigma19971 enigma19971 转载需注明出处Symbiann系统已经提提供了一套已已经定义好的的内置的数据据类型。为了了保证你的代代码是编译器器无关的,应应当使用下面面symbiian系统提提供的数据类类型,而不要要使用原生数数据类型(nnativee typees,这里指指标准C中的的int ,char等等)。基本类型TIntX 和和 TUinntX (其其中X = 8, 166 和 322) 分别用用来表示 88位, 166位 和 332位的有符符号和无符号号的整数。 一般情况下下,使用TIInt 和TTUin

2、t就就可以了,除除非是在考虑虑代码优化或或兼容性的时时候,才会用用到TIntt8,TInnt16这样样的类型。TTInt 或或 TUinnt 类型分分别对应有符符号和无符号号的整数。TInt64. 在版本88.0之前,SSymbiaan系统中不不支持64位位的算术运算算,而是用两两个32位的的值来实现664位的整数数,在8.00版本之后,TTInt644和TUInnt64才被被定义为loong loong类型,真真正使用644位的内置数数据类型。TReal322 和 TRReal644 (TReeal相当于于TReall64) 这两个个数据类型相相当于单精度度和双精度的的浮点数,由由于浮点数的

3、的运算要比整整数慢,所以以一般应尽量量避免使用浮浮点数的运算算。TTextX (其中X = 8 或或 16) 分别对对应窄或宽的的字符(注:所谓窄字符符通常ASCCII码字符符,而宽字符符是指uniicode字字符集的字符符 )TAny*TAny* 意意为指向任意意内容的指针针,在这种意意义上讲,TTAny相当当于voidd, TAnny* 相当当于TAnyy*。但是,在在某些场合下下,voidd标示空,如:void hhello(void);这时,不要将它它改写为: TAnyy helllo(TAnny);TBool 标示布尔类型。SSymbiaan系统提供供了两个常量量:ETruue (=

4、11) 和 EEFalsee (=0),分别表示示真和假。注意:在Symmbian系系统中,TBBool被定义义为int, 而ETruue和EFalsse被定义为为enum,所所以,如果一一个函数的返返回值为TBBool,不不要用如下的的代码来比较较函数的返回回值:TBool iisLargger(TIInt a, TIntt b)return (ab)?ETruue:EFaalse; if(isLaarger(4,3)=ETruue). /错误误,编译不过过。if(isLaarger(4,3). /正确2类和对象2.1 Symmbian系系统中的命名名习惯:在Symbiaan系统中编编写代码

5、时,应应当遵守种样样几个规则:成员变量的的命名以小写写字母i开头头,方法的参参数以小写字字母a开头,例例如:class PPernonnpublic:TInt iiAge;void SSetAgee(TIntt aAgge)iAAge = aAge;在symbiaan系统中存存在几种不同同类型的类(cclass),不不同类型的类类,其特性也也各不相同。有的在堆(heeap)上创创建,有的在在栈(staack)上创创建,特别的的是,类的实实例(insstancee)的清除方方式也不尽相相同(下面,为为了方便我们们把类的类别别称为型别)。型型别(claass tyype)可以以体现这些不不同的特点

6、。每每个型别都有有一套定义好好的关于如何何创建和清除除实例的规则则。为了容易易区分型别,SSymbiaan系统使用用了一个简单单的命名规则则:类名以大大写字母开头头(T,C,RR 或M)。作作为类的设计计者,你先要要考虑这个类类的行为,看看它到底与哪哪种型别匹配配,一旦确定定了它的类型型,然后你就就可以专注于于该类的功能能。同样,对对一个类的使使用者来讲,如如果他不熟悉悉这个类, 但类的命名名规则可以帮帮助他弄清你你的意图-如如何用安全的的方式初始化化、使用和销销毁一个类的的对象(obbject)。下面,我主要讨讨论不同型别别的主要特性性。T 类T类的行为类似似于C+中中的内置类型型,因此,它

7、它们以T作前前缀(”T”代表”Type”)。象内置置类型一样,它它们没有析构构方法(deestrucctor),这这导致的结果果是:T类不不能包含具有有析构方法的的成员变量。所所以,一般情情况下,T类类的成员变量量只能是内置置类型的数据据或者是其它它的T类的对对象。在某些些的情况下TT类也可以包包含其它对象象的指针或引引用,不过,这这时它们之前前是“使用”关系,而不不是“拥有”关系(也就就是说,这个个T类对象并并不负责对成成员的创建和和销毁的工作作)。不能拥拥有外部数据据的原因是因因为T类没有有析构方法。正正是由于没有有析构方法,TT类的对象可可以在栈上创创建,当程序序流程退出函函数或产生ll

8、eave(一一种代码异常常)的时候,系系统自动清除除它。即使TT类有一个析析构方法,在在发生异常(在在Symbiian系统中中,异常被称称为leavve)时Syymbiann 系统也不不会调用它,因因为leavve没有模仿仿标准C+的抛出异常常的做法。T类的对象也可可以在堆上创创建。但是,应应当在调用有有可能发生异异常的代码之之前,将这个个对象放入到到清除栈(clleanuppStackk),在发生生异常的时候候,清除栈(clleanuppStackk)会释放这这个对象。C 类这种类都是从CCBase派派生来的(直直接或间接)。/.h fiileclass CCStudeent:publiic

9、 CBasee publicc:CStudeent()RDebuug:Prrint(_L(i am a studeent);CStuddent()RDebuug:Prrint(_L(pllease, dont killl me!);void SSampleeFuncttion();privatte:TInt iiCode;TInt iiScoree;CBase有两两个特点:首首先,它有一一个虚的析构构方法,这样样,可以通过过CBasee指针来删除除它的子类。代代码如下所示示:CBase *pStu = neww CStuudent();delete pStu;结果: ii am aa stud

10、dent pleasee, donnt kiill mee! 其次,CBasse类和它的的子类,重载载了new操操作符,这使使得当它在堆堆上创建的时时候,自动初初始化为0,也也就是说,当当它一开始被被创建出来的的时候,所有有的成员变量量都被初始化化为0,所以以您不必在构构造方法中去去做这件事情情。但是,在在栈上创建对对象时,情况况并非这样, 因为这时没没有用到neew操作。这这将潜在地导导致堆上创建建的对象和栈栈上创建的对对象的行为不不一致。因此此,C类的对对象一定要在在堆上创建。很明显,当一个个堆上的C类类对象不再被被需要时,我我们需要消耗耗它。 一个个C类的对象象可能以两种种方式存在:其它

11、类的指指针成员变量量或是一个局局部的针指变变量。在前一一种情况下,我我们可以在类类的析构方法法中调用deelete来来删除它;后后一种情况要要复杂一些,在在调用任何有有潜在的异常常(leavve)的代码码之前,要把把这个指针放放到清除栈(ccleanuup staack)中,否否则有可能发发生内存泄露露。CBasse 类声明明了私有的拷拷贝构造方法法和赋值操作作(=)。这这是一个很好好的策略,它它可以用来防防止客户代码码不小心地使使用了浅拷贝贝或赋值的方方法。由于基基类的拷贝构构造和赋值是是私有的,所所以,如果您您希望您的类类可以能够使使用拷贝构造造方法,您必必须显式地声声明和定义拷拷贝构造方

12、法法和赋值操作作。但是,考考虑到C类的的特性,深拷拷贝可能造成成发生异常(lleave)的的隐患,而您您绝对不能让让类的构造方方法(或析构构方法)发生生异常(我们们在本教程的的后面解释原原因)。所以以,如果您确确实需要一个个拷贝的方法法,那么您可可以为类添加加一个的可能能会发生异常常的方法来完完成同样的任任务,例如:CloneeL()或CCopyL()。如果您您提供的这个个类是从CBBase派生生的,您就不不必为了防止止客户代码使使用有潜在安安全问题的“浅”拷贝,而在在代码中将这这些方法声明明为私有的。R 类前缀“R” 在在这里代表资资源(Ressourcee), 通常常是外部资源源,例如:文

13、文件的句柄(hhandlee)。 和C类不同,SSymbiaan系统中不不存在一个对对应的RBaase类,所所以一个R类类应当有一个个构造方法来来将它的资源源句柄置为00,表明还没没有资源和这这个新建的对对象关联在一一起。但是,不不要在构造方方法中初始化化资源句柄,因因为这样有可可能使构造方方法产生异常常。R类中常常常有类如OOpen(), Creeate() 或 Innitiallize()这样的方法法,它们用来来分配资源,设设置句柄成员员变量的值,并并返回错误代代码或是产生生异常。 RR类通常也有有对应的Cllose()或或Resett()类,用用来释放资源源,重置句柄柄的值-表明明没有资

14、源和和该对象关联联。使用R类类时,一个常常见的错误是是忘记调用它它的Closse()方法法(当然,该该方法也可以以是其它名字字,但它经常常被命名为CClose()或或是有一个析析构方法释放放资源,这会会引起资源的的泄露。R类通常都很小小,除了资源源句柄没有其其它的成员变变量。因为不不需要。它通通常也没有析析构方法,资资源的释放都都是在Cloose()方方法中进行的的。大多数情情况下,R类类都是作为类类的成员变量量或局部变量量存在的。只只有少数情况况下,在堆上上创建。您必须确保,当当程序发后异异常的时候,资资源能被正确确地释放-通通常是使用资资源栈。如果果一个R类是是一个堆上的的自动变量(相相对

15、于成员变变量),您一一但要保证资资源被释放,而而且,变量本本身也要被释释放。typicallly byy usinng twoo pushh callls: ClleanuppCloseePushLL(), oor asiimilarr funcction,to ennsure that the rresourrce iss cleaaned uup, annd a sstandaard ClleanuppStackk:PusshL(TAAny*) whichh simpply caalls UUser:Free() on the hheap ccell.R类的成员变量量通常都很简简单,所以一

16、一般不需要深深拷贝(biitwisee copyy)。R类的的拷贝可能会会引起混乱(想想象一下:如如果两个对象象同时在一个个资源句柄上上调用Cloose()方方法,或两个个对象都没有有释放资源,会会发生什么情情况?)如果果,您想阻止止任何对R类类的拷贝,您您应当声明(但但不定义)一一个私有的构构造方法和赋赋值操作。M 类当提到多继承的的时候,它意意味着从一个个主要的类派派生,同时也也混杂基它类类的功能。前前缀M是单词词Mixinn的首字母。SSymbiaan系统不赞赞成多继承的的做法,因为为这个引入额额外的复杂性性,M类是一一个抽象类,它它的作用相当当于javaa中的接口(iinterffac

17、e)。在在Symbiian系统中中,M 类常常被用来定义义回调接口或或者是观察者者(obseerver)类类。M类也可可以被其它类类继承。下面面我们给出两两个例子。class MMAnimaalpublicc:virtuaal void EatL() =0;class MMDomessticAnnimal : pubblic MAnimmalpublicc:virtuaal void NameLL() =00;class CCCat : publlic CBasee, publlic MDomeesticAAnimallpublicc:virtuaal void EatL(); / 从MAni

18、mmal, 经经过MDommesticcAnimaal继承virtuaal void NameLL(); / 从 MDommesticcAnimaal继承/ Othher fuunctioons ommittedd for clariity;上面的例子演示示了一个从CCBase类类和一个M类类派生的具体体类。而类MMDomessticAnnimal又又是从MAnnimal派派生的。象接接口一样,由由于不能被实实例化,M类类只能有虚(vvirtuaal)函数,不不能有成员变变量和构造方方法。但它可可以有析构方方法, 条件件是,实现它它的具体类必必须是从CBBase派生生的。在定义义完类以后,然然

19、后可以用使使用它。代码码如下:CCat *catt1 = new CCCat;delete cat11; /正确然下面的代码却却是错误的。MAnimall *catt2 = neww CCatt;delete cat11; /错误当用M类的指针针引用一个对对象的时候,如如果用dellete删除除这个指针,则则这个M类必必须提供一个个虚拟的析构构方法,否则则会出现系统统异常(paanic ccode 442)。将MMAnimaal的代码改改写,则上面面代码没有问问题。class MMAnimaalpublicc:virtuaal void EatL() =0;virtuaal MAniimal(

20、); /增加一个个虚的析构方方法。;3描述符(deescripptor)在Symbiaan 系统中中,字符串被被称为“描述符”(desccriptoor),因为为它们是自我我描述的。在在描述符中保保存了它所表表示的字符串串的长度和它它的底层的内内存布局的信信息。描述符符比标准C中中的字符数组组和字符指针针要复杂,您您可能需要多多花些时间来来学习和掌握握它的用法。关关键是,它们们的特殊设计计使得它们在在少量内存的的设备上非常常有效率,仅仅用非常少的的内存就可以以保存自己的的长度和内存存布局的信息息。现在,让让我们来深入入了解描述符符的设计思想想。在Symbiaan系统中,描描述符是相当当让人迷惑

21、的的,因为它的的种类繁多。不不同种类的描描述符具有不不同的特性和和用法,但又又经常能相互互转换。它们们不同于标准准C+中的的strinng,javva语言中的的strinng类或MFFC中的CSStringg,因为程序序员必须自己己管理底层的的内存分配和和清除工作。它它们具有防治治内存溢出的的机制,并且且不依赖NUULL终结符符号来决定字字符串的长度度,从这方而而来讲,它也也不同于C语语言中的字符符串。现在我们来讨论论:什么是描描述符?它们们是如何工作作的?在探讨讨这些不同的的描述符之前前,先让我们们需要弄清楚楚一个基本的的概念:什么么是字符串数数据的“宽度”?这个长度度指的是单个个字符是8b

22、bit的,还还是16biit的宽度。在在早期的版本本中,字符的的宽度都是88bit的,后后来为了支持持Unicoode字符集集,从第5版版起,Symmbian系系统将16bbit 的字字符作为标 准。Symmbian系系统现在支持持这两种字符符长度的描述述符,除了CCopy()和Size()两个方法法以外,这两两种宽度的描描述符的行为为是完全一致致的,这两个个方法的使用用,我们后面面再介绍。另另外,有一套套中立的描述述符类型,它它们既可以被被定义为窄的的描述符类型型,也可以被被定义为宽的的描述符类型型,这要取决决于编译时的的宽度。您可可以从它的名名字上很容易易看出这个类类型所表示的的宽度。假如

23、如,它以8结结尾(例如:TPtr88,就意味着着它表示是的的8bit的的窄字符,而而以16结尾尾的描述符类类(例如:TTPtr166)则操作116bit的的宽字符。 对中立(nneutraal)的类型型来讲,没有有数字结尾(例例如:TPttr),在Symbbian系统统第5版以后后,默认的情情况下,它们们表示宽度为为16bitt的字符串。它它们之间的关关系比较类似似于TIntt,TIntt16或TIInt32 之间的关系系,这一点应应当是比较易易于理解的。一般情况下,您您没有必要指指明是字符串串的宽度,用用中立的类型型就可以了,这这样使你的代代码易于在宽宽字符版本和和窄字符版本本之间转换(有有

24、过编程经验验的朋友应该该有这样的印印象,我们平平常写代码,大大多情况下,仅仅仅使用UIINT类型,而而较少考虑使使用UINTT16,UIINT32类类型)。另外一个问题是是:描述符和和字面量(lliteraal)的区别别。所谓字面面量是指在编编码的时候就就已经确定的的量,例如,标标准C中的 char* pp = HHello worldd;其中的Helllo woorld就就是字面量。在在Symbiian系统中中,对它们的的处理是很不不一样的,这这点我们在后后面再介绍。有了这样的一些些认识, 现现在我们可以以来看看有哪哪些描述符类类型。在Syymbiann系统中描述述符类型有两两大种类:不不可

25、修改(nnon-moodifiaable)的的描述符和可可修改(moodifiaable)的的描述符。3.1不可修改改(non-modiffiablee)的描述符符 在Symbiaan系统中,所所有的描述符符都继承自TTDesC,在在前面我们已已经讨论了类类名前缀T所所代表的意义义,在这里,我我们更关心类类名的后缀CC所代表的意意义,这个CC是单词Coonstannt的首字符符,表示这个个类是不可更更改的。这个个类提供了一一些用来返回回字符串的长长度和操作数数据的方法。LLengthh()方法返返回了描述符符的长度,因因为,每个描描述符对象在在内存中的布布局都是同样样的,用4个个字节来表示示它

26、所包含的的数据的长度度(实际上,只只用了32个个bit中的的28个biit,剩余的的4bit留留作它用,所所以描述符能能表示的最大大的长度为2228 字节节,256 MB,不过过这已经足够够了)。所以以,Lenggth()方方法没有被它它的子类重写写,它对所有有子类都有效效。但是,根根据实现子类类的方法的不不同,子类访访问数据的方方式也不一样样,Symbbian系统统不要求它的的子类通过虚虚函数的方式式来实现自己己的访问数据据的方法。 不用虚函数数重写的原因因是因为,虚虚函数会给每每个被派生的的描述符对象象增加4节字字的额外负担担,c+用用这4个字节节来存放指向向虚函数表的的指针。我们们前面说

27、过,在在设计描述符符的时候要让让它尽可能高高效,额外的的字节开销被被认为是不理理想的。存放放长度的4个个字节中,228bit用用来表示长度度,剩下的44bit用来来表示描述符符的类型。目目前,symmbian系系统中有5种种派生的描述述符类型,44bit限制制了描述符的的种类最多只只能有16种种,但这已经经足够了。子子类可以通过过调用基类TTDesC的的Ptr()方方法来访问描描述符的数据据,Ptr()方法检查查这4个biit,确定描描述符的类型型并返回它的的数据在内存存中的地址。当当然,这要求求TDesCC基类清楚它它的子类的内内存布局,并并在Ptr()方方法中使用硬硬编码的方法法。后面,为

28、为了表述上的的方便,我们们也把这种不不可修改的描描述符也称为为常量描述符符(consstant descrriptorr)总结:不可修改改的描述符类类TDesCC是所有的非非字面量描述述符的基类,它它提供了确定定描述符长度度和访问数据据的方法,另另外,它实现现了所有的您您想用来处理理常量字符串串的操作。3.2可修改(mmodifiiable)的的描述符所有的可修改的的描述符都从从TDes基基类派生,而而TDes本本身又是从TTDesC派派生的。TDDes有一个个额外的成员员变量用来存存放为该描述述符分配数据据的最大长度度。MaxLLengthh()方法返返回了这个最最大的长度。像像TDesCC

29、中的Lenngth()方方法一样,MMaxLenngth()方法也不被被TDes的的子类继承。TDes类提供了一系列的方法, 用来对可修改字符串数据的操作,包括对字符串的附加、填充和格式化操作。所有的这些方法都被派生类继承,派生类只实现一些特定的构造方法和复制赋值的方法。这些方法都不负责分配内存,假如它们超过了描述符的数据长度,例如,用Append()方法在某个字符串后面附加另一个字符串时,在调用该方法之前,您必须确保有足够的内存空间。当然,只要不超过描述符的最大存储容量,描述符的长度可以自由地伸缩。当描述符长度比最大长度短的时候,描述符的后面部分是多余未用的。这些方法使用了断言(assert

30、ion)来确保描述符的最大长度不会被超出。如果发生内存溢出,将会产生一个panic(关于panic,我们将在后面的章节介绍),这样可以方便您检查和修正程序的错误。事实上,不可能能使描述符溢溢出,这一点点保证了您代代码的强壮性性,而且不易易产生难以跟跟踪的内存陷陷阱。但需要注意的是是,由于基类类的构造方法法是protteced类类型的,所以以您无法直接接实例化一个个TDesCC或TDess类的实例。现现在我们来看看看描述符的的派生类,您您可以实例化化和使用派生生类的对象。正正如前面所说说,这个地方方是比较让人人迷惑的,因因为描述符存存在大量的派派生类。 前前面,我们已已经解释过为为什么每个类类会

31、有三个不不同的版本,例例如:TDees8, TTDes166 和 TDDes,分别别对应窄字符符,宽字符和和中立的类。现现在,让我们们看看有哪些些主要的描述述符类型,在在深入讨论每每种类型的细细节之前,我我们先考察一一下它们在一一般情况下的的内存布局。描描述符有两种种基本的内存存布局:指针针描述符和缓缓存区描述符符。不同之处处在于,指针针描述符持有有一个指向字字符串的指针针,而这个字字符串存储在在内存中的基基它位置。与与指针描述符符不同,缓存存区描述符本本身持有字符符数据,也就就是说字符数数据本身构成成了描述符的的一部分。总结:TDess 是所有的的可修改的描描述符的基类类, 并且它它自己也是

32、从从TDesCC派生的。它它有一个能返返回最大的内内存容量的方方法和一系列列的用来修改改字符串数据据的方法。3.3 指针描描述符(poointerr desccriptoor)指针描述符可分分为两种:TTPtrC 和TPtr(我我们前面说过过,每种类型型的描述符,按按照字符宽度度,都可以分分为三个版本本,例如:窄窄字符版本TTPtrC88,宽字窄版版本TPtrrC16和中中立的版本TTPtrC,所所以严格来讲讲,有六种指指针描述符)。指针描述符所持有的字符串是跟描述符本身分开来存放的,它可以被存储在ROM中,堆中或栈中。由于保存数据的内存既不为描述符所拥有,也不通过它来管理。所以,如果要该描述

33、符是在堆上分配的,那么应通过堆描述符(HBufC,下面将要讲解)来操作内存的分配和销毁;如果指针描述符所指向的字符串是在栈上分配的,那这个内存必须是已经在栈上分配好的。通常情况下,指针描述符是基于栈的,但有时候,它们也可以在堆上使用,例如:作为一个CBase派生类的成员变量的时候。在不可修改的描述符(TPtrC)中,指向数据的指针存放在长度的后面,因此,指针描述符的总长度为2个字(word);在可修改的指针描述符中,它存放在最大长度的后面,因此,总长度为3个字。下图比较了TPtr和TPtrC内存布局.iLengthiLength(12)iMaxLengthiPtrHello world!iLe

34、ngth(12)iPtrTPtrCTPtr TPtrCTPtrC相当当于C语言中中的consst chaar*。被它它指向的数据据可以被访问问但不能被修修改:也就是是说,描述符符中的数据是是常量。所有有的从基类TTDesC中中继承的操作作都是可访问问的。TPttrC定义了了一系列的构构造方法,使使得它能从其其它的描述符符、指向内存存的指针或以以0结尾的CC语言字符串串构造。/ 字面量描描述符将在后后面介绍_LIT(KLLiteraalDes, Sixxty ziipperss weree quicckly ppickedd fromm the wovennjute baag);TPtrC pp

35、angraamPtr(KLiteeralDees); / 从字面面量描述符构构造TPtrC ccopyPttr(panngramPPtr); / 从其其它的描述符符构造TBufC cconstBBufferr(KLitteralDDes); / 常量量缓存区描述述符,后面介介绍TPtrC pptr(coonstBuuffer); / Consttructeed froom a TTBufC/ TTexxt8 iss a siingle (8-biit) chharactter, eequivaalent to unnsigneed chaarconst TTText88* cSttring =

36、 (TTText8*)Walltz, bbad nyymph, for qquick jigsvex;/ 从以0结结尾的字符串串构造TPtrC8 anothherPtrr(cStrring);TUint8* memooryLoccationn; / Pointter innto meemory initiializeed elssewherreTInt leength; / LLengthh of mmemoryy to bbe reppresennted.TPtrC8 memPttr(memmoryLoocatioon,lenngth); / 从从一个指针构构造。这个指针本身可可以改变成指指

37、向其他的字字符串数据(通过Sett()方法)。如果您想想指明,不能能改变您的TTPtrC所所指向的数据据,那么您可可以将TPttrC声明为为constt,这样,当当您试图用SSet()方方法更改TPPtrC所指指向的数据时时,编译器会会产生警告。/ 字面量描描述符_LIT(KLLiteraalDes11, Siixty zzipperrs werre quiickly pickeed froom thee woveen juttebag);_LIT(KLLiteraalDes22, Waaltz, bad nnymph, for quickk jigss vex);TPtrC aalpha(K

38、LiteeralDees1);TPtrC bbeta(KKLiterralDess2);alpha.SSet(KLLiteraalDes22); / alphha poiints tto thee dataa in KKLiterralDess2beta.Seet(KLiiterallDes1); / beta pointts to the ddata iin KLiiterallDes1const TTPtrC gammaa(betaa); / Poinnts too the data in beeta, KKLiterralDess1gamma.SSet(allpha); / GGener

39、aates aa warnning, but ppointss to aalpha这里应当加一些些示范代码TPtrTPtr 是可可修改的指针针描述符,它它可用来访问问和修改字符符串或二进制制数据。TDDesC 和和TDes所所提供的所有有的操作都适适用于TPttr。这个类类定义了一些些构造方法,使使得它能从指指向内存的指指针构造,并并设置适当的的长度值和最最大长度值。编译器也会产生生隐式的构造造方法和拷贝贝构造方法,因因为它们没有有被声明为保保护的或私有有的。一个TTPtr对象象可以从其它它的可修改描描述符构造,例例如:通过在在不可修改的的描述符上调调用Des()方方法,这个方方法返回一个个如

40、下所示的的TPtr对对象:_LIT(KLLiteraalDes11, Jaackdawws lovve my big ssphinxx of qquartzz);TBufC buuf(KLiiterallDes1); / TBufCC are descrribed laterrTPtr pttr(buff.Des(); / Coppy connstrucction; can modiffy thee dataa in bbufTInt leength = ptrr.Lenggth(); / LLengthh = 377TInt maaxLenggth = ptr.MMaxLenngth();

41、/ Maximmum leength = 60, as ffor buufTUint8* memooryLoccationn; / Validd poinnter iinto mmemoryy.TInt leen = 112; / Lenggth off dataa to bbe reppresenntedTInt maaxLen = 32; / MMaximuum lenngth tto be repreesenteed/ Consstructt a poointerr desccriptoor froom a ppointeer intto memmoryTPtr8 mmemPtrr(me

42、mooryLoccationn, maxxLen); / llengthh = 0, max lengtth = 332TPtr8 mmemPtrr2(memmoryLoocatioon, leen, maaxLen); / lengtth = 112, maax = 332另外,TPtrr提供了赋值值运算符=(),用来拷拷贝数据到指指针所指向的的内存(数据据源可以是可可修改、不可可修改的指针针描述符,或或以0结尾的的字符串)。如果要拷贝的数据的长度超过了描述符的最大长度,会引发一个系统异常。像TPtrC一样,TPtr也定义了一个Set()方法,用来改变描述符所指向的数据。_LIT(KLLit

43、eraalDes11, Jaackdawws lovve my big ssphinxx of qquartzz);TBufC buuf(KLiiterallDes1); / TBufCC are descrribed laterrTPtr pttr(buff.Des(); / Poiints tto thee conttents of buufTUint166* memmoryLoocatioon; / Valiid poiinter into memorry.TInt maaxLen = 40; / MMaximuum lenngth tto be repreesenteedTPtr me

44、emPtr(memorryLocaation, maxLLen); / leength = 12, max lengtth = 440/ Copyy and replaacememPtr = ptrr; / memPttr datta is KLiteeralDees1 (337 byttes), maxLeength = 40_LIT(KLLiteraalDes22, Thhe quiick brrown ffox juumps oover tthe laazy doog);TBufC bbuf2(KKLiterralDess2); / TBuufC arre desscribeed lat

45、terTPtr pttr2(buuf2.Dees(); / PPointss to tthe daata inn buf/ Repllace wwhat pptr pooints toptr.Sett(ptr22); / ptr pointts to conteents oof buff2, maax lenngth = 100memPtr = ptrr2; / Atteempt tto upddate mmemPtrr whicch pannics bbecausse thee/ conttents of pttr2 (443 byttes) eexceedds maxx lenggth o

46、ff memPPtr (440 byttes)您一定不要混淆淆了Set()方方法和=()赋值操作。前前者将描述符符的指针重置置,使它指向向新的数据区区域,而后者者将数据拷贝贝到描述符中中,一般来说说,这会更改改描述符的长长度,但不会会更改它的最最大长度值。3.5 基于栈栈(stacck-bassed)的缓缓冲区描述符符基于缓冲区的描描述符也可以以分为可修改改的TBuff和不可修改改TBufCC的两种类型型。对这种描描述符来讲,字字符串数据本本身就是描述述符的一部分分。下图给出出了描述符的的内存布局:iLength 12iLength 12iMaxLengthHello World!TBufiL

47、ength 12Hello World!TBufC这两种描述符通通常用来存储储定长的或相相对较小的字字符串,常用用来存放长度度小于2566个字符的文文件名。类似似于C语言中中的charr,但是是,它们具有有检查内存溢溢出的功能。TBufCTBufC是不可修修改的缓冲区区类型,它主主要用来存放放字符串常量量或是二进制制数据。该类类从TBuffCBasee类派生,尖尖括号内内的数字表示示分配给该描描述符的数据据区的大小。它定义了一些构造方法,允许从其它的描述符或以0结尾的字符串构造。也允许创建一个空的描述符,然后再填充。由于该描述符的的数据是不可可修改的,它它的整个内容容可以被置换换(通过该类类的

48、所定义的的赋值操作),用用来置换的数数据可以是其其它的不可修修改的描述符符或是0结尾尾的字符串,但但是,无论是是何种情况,新新数据的长度度都不能超过过长度n(也也就是创建该该类的时候指指定的模板参参数)。_LIT(KPPalinddrome, Sattan, ooscilllate mmy mettallicc sonaatas);TBufC buuf1(KPPalinddrome); / Consttructeed froom litteral descrriptorrTBufC buuf2(buuf1); / Coonstruucted from buf1/ Consstructted f

49、rrom a NULL-termiinatedd C sttringTBufC buuf3(TTText*)Nevver oddd or even);TBufC buuf4; / Connstruccted eempty, lenggth = 0/ Copyy and replaacebuf4 = buf1; / bbuf4 ccontaiins daata coopied from buf1, lenggth moodifieedbuf1 = buf3; / bbuf1 ccontaiins daata coopied from buf3, lenggth moodifieedbuf3 =

50、buf2; / PPanic! Max lengtth of buf3 is innsuffiicientt for buf2 data该描述符中的数数据可以被整整体置换,但但不能被直接接修改,但有有时候我们的的确需要修改改缓存区中的的数据,该怎怎么办呢?系系统提供了另另一种途径来来修改数据。该该类定义了DDes()方方法,它为缓缓存区中的数数据返回一个个可修改的指指针描述符(TTPtr)。我我们可以通过过这个指针描描述符间接地地修改缓冲区区中的数据。当当数据通过指指针描述符被被修改以后,指指针描述符和和缓冲区描述述符中的iLLengthh的值会跟着着改变,但要要记住,缓存存区描述符的的长度值

51、只可可能减小,而而是不可能增增大的,因为为,描述符类类是不提供内内存管理管理理功能的。_LIT8(KKPalinndromee, Saatan, oscilllate my meetalliic sonnatas);TBufC8 bbuf(KPPalinddrome); / Consttructeed froom litteral descrriptorrTPtr8 pptr(buuf.Dess(); / daata iss the strinng in buf, max llengthh = 400/ Illuustrattes thhe usee of pptr too copyy and

52、 replaace coontentts of bufptr = (TTextt8*)DDo Geeese seee Godd?;ASSERT(ptr.LLengthh()=bbuf.Leength();_LIT8(KKPalinndromee2, AAre wee not drawnn onwaard, wwe feww, draawn onnward tonew eraa?);ptr = KKPalinndromee2; / Paniic! KPPalinddrome22 exceeeds mmax leength of pttr(=400)TBuf这也是一个模板板类,它是一一个可修改的的

53、缓冲区描述述符类,后面面的表表示缓冲区大大小。TBuuf从TBuufBasee类派生,而而TBufBBase是从从TDes派派生的,因此此,它继承了了TDes和和TDesCC类所有的方方法。像TBBufC一样,TTBuf也定义了了一系列的构构造方法和赋赋值操作。对对所有的描述述符类型来讲讲,内存管理理是您的责任任,尽管这个个缓冲区中的的数据是可修修改的,但它它的长度不能能超过在构造造方法中所给给定的最大值值(n)。假假如缓冲区的的内容需要扩扩展,那么您您必须决定是是在编译的时时候就给定一一个足够大的的值,或是在在运行的时候候动态分配内内存。但无论论哪种情况,都都要确保数据据长度不要超超过缓存区

54、的的最大长度。如果需要使用动动态分配的内内存,您可以以使用基于堆堆的描述符,这这个我们在后后面要讲到。要要是您觉得管管理内存分配配的任务太过过繁重,您也也可以选择使使用动态数组组。不过,您您应当记住,使使用动态数组组的额外开销销是很高的。_LIT(KPPalinddrome, Sattan, ooscilllate mmy mettallicc sonaatas);TBuf buff1(KPaalindrrome); / CConstrructedd fromm liteeral ddescriiptorTBuf buff2(buff1); / Connstruccted ffrom ccon

55、staant buuffer descrriptorrTBuf8 buuf3(TTText88*)Doo Geesse seee God?); / froom C sstringgTBuf buff4; / Consstructted emmpty, lengtth = 00, maxximum lengtth = 440/ Illuustratte coppy andd repllacebuf4 = buf2; / bbuf2 ccopiedd intoo buf44, upddatingg lenggth annd maxx lenggthbuf3 = (TTexxt8*)Murdeer

56、forr a jaar of red rrum; / uppdatedd fromm C sttring3.6 基于堆堆的(Heaap-Bassed)缓冲冲区描述符当您要使用非常常长的字符串串时,有另外外一种选择:基于堆的描描述符。它能能拥有比它的的创建者更长长的生存期。当当您在编译的的时候还不能能确定缓冲区区长度的时候候,堆描述符符也是很有用用的,这时,它它的作用相当当于C语言中中的mallloc。HBufC也许您已经发现现,HBuffC的类名以以“H”开头,这不不符合Symmbian系系统中惯用的的命名习惯。这这的确是一个个特例,“H”表示这个类类一般是在堆堆(Heapp)上分配的的。HB

57、uffC定义了静静态的NewwL()方法法,用来在堆堆上创建一个个缓存区。正正如您所见到到,HBuffC中的字母母“C”表示这个表表述符是不可可修改的。对对该类的操作作几乎和TBBufC一样:该该类提供了一一套赋值操作作,允许整个个缓冲区中的的内容被替换换掉;同样,新新内容的长度度不能超过缓缓存区的大小小,否则会引引起系统异常常;通过调用用Des()方法,可以以返回一个可可修改的指针针描述符(TTPtr),可可以通过这个个指针描述符符来更改缓冲冲区中的内容容。_LIT(KPPalinddrome, Do Geesee see God?);TBufC sttackBuuf(KPaalindrro

58、me);/ Alloocatess an eempty heap descrriptorr of mmax leength 20HBufC* heapBBuf = HBufCC:NewwLC(200);TInt leength = heaapBuf-Lenggth();/ Cuurrentt lenggth = 0TPtr pttr(heaapBuf-Des(); / Moddificaation of thhe heaap desscripttorptr = sstackBBuf; / Coppies sstackBBuf coontentts intto heaapBuflength =

59、heaapBuf-Lenggth(); / llengthh = 177HBufC* heapBBuf2 = stacckBuf.AlloccLC(); / FFrom sstack buffeerlength = heaapBuf22-Lenngth(); / lengtth = 117_LIT(KPPalinddrome22, Paalindrrome);*heapBuuf2 = KPaliindromme2; / Coppy andd repllace ddata iin heaapBuf22length = heaapBuf22-Lenngth(); / lengtth = 110Cl

60、eanuppStackk:PoppAndDeestroyy(2, hheapBuuf);记住,堆描述符符可以按您的的要求的尺寸寸动态分配内内存,但它不不会自动按您您的期望更改改缓冲区的大大小。在修改改缓存区 的的内容之前,您您要确保缓存存区的内存是是足够的。为为了帮您简化化这些操作,HHBufC提提供的一套RReAlloocL()方方法,它可以以用来扩展堆堆的缓存区(这这个操作有可可能会使缓冲冲区从一个内内存区域搬到到另一个区域域)。If the HBufCC* is storeed on the ccleanuup staack, mmovingg the pointter ass a re

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论