Symbian C++描述符

简介: 习惯了java,C#这些语言的开发,在symbian要转换一下思维,字符串处理就是一个例子,string用起来真叫人简单,自从看了symbian hello world例子,发现,竟然写一个hello world也不是那么容易,连字符串也不是string a="hello world",取而代之的是描述符。
习惯了java,C#这些语言的开发,在symbian要转换一下思维,字符串处理就是一个例子,string用起来真叫人简单,自从看了symbian hello world例子,发现,竟然写一个hello world也不是那么容易,连字符串也不是string a="hello world",取而代之的是描述符。因为手机开发,对于内存管理很重要,默认栈的大少是8kb。字符串和二进制文件划分为一类,统一由描述符管理。 

背景 

描述符是Symbian C++字符串的描述类,不同于string,它既可以表示字符串,也可以表示二进制数据;同时支持8位和16位,但是用来存储字符串时并不需要指定哪种类型 ,而是由编译时的设置决定,也可以在创建对象时声明,如TDes8,TDes16等等 

      #if defined(_UNICODE) 
          typedef TPtrC16 TPtrC 

        else 
          typedef TPtrC8 TPtrC 

  一般来说用来存储二进制数据时通常使用8位版本。 
上面的宏定义在symbian里面到处可见,在e32def.h里面,有很多symbian重新定义的类型。 

类型 

描述符可以分为五大类,分别是抽象描述符、文字描述符、缓冲区描述符、指针描述符和堆缓冲区描述符。下图为类继承关系图(抽象类不能创建对象,一般用于参数,C结尾的为不可修改const) 


说明 

1、抽象描述符 
    抽象描述符包含TDesCTDes,TDes 是从TDes派生的,因为这些类是抽象的,所以不能实例化,它们多数用于函数参数。TDesC是所有描述符的基类,而TDes与TDesC不同的是 TDes可以对数据进行修改,并引入数据最大长度的概念。因为它是所有描述符的基类,继承它的所有类型都拥有它的方法。 
  2、文字描述符 
    文字描述符是我们用的比较多,它主要用来保存字符串常量,常用方法如下: 
_LIT(KHelloWorld,"Hello World!"); 
_L("Hello world!"); 
上面是根据宏定义来建立文字描述符对象,建议这样使用,不建议使用TLitC来创建文字对象; 



当使用_LIT()宏的时候,产生的其实是一个TLitC对象(8位或16位),数据实际上被存储在装载到RAM的二进制应用程序内,虽然它们实际上并不存储在ROM(或与ROM类似的闪存)中,所以可以把它们看成是只读的 
可以使用()操作符将描述符转换成常量的TDesC对象,比如: 
TInt length=KHelloWorld().Length(); 


3、缓冲区描述符 
  缓冲区描述符TBufCTBuf将它们的数据存储为本身的一部分,既然该描述符使用在编译时就确定的固定数量的内存,因此可以在栈上对其进行声明(作为局部或者成员变量),这里看个小例子。 

_LIT(KHelloWorld,"Hello World"); 
const TInt maxBuf=32; 
... 

TBufC<maxBuf> buf;//空缓冲器,长度为0,从这里也可以看得出,缓冲描述符一定要声明一个长度。 

TInt currentLen=buf.Length();//==0 
buf=KHelloWorld;//在构造函数之后设置内容 

currenLen=buf.Length();//==11 
TText ch=buf[2]//=="l" 


  这里要注意的是TBufC是TDesC的子类,而TBuf是TDes的子类,因此TBuf也提供了修改数据等的多种功能。后面会总结它的修改的方法。 

4、指针描述符 

      指针描述符TPtrCTPtr用于引用存储在别处的、不属于该描述符所拥有的数据。使用TPtr或者TPtrC来访问字符串比维护指向零值终止(zero-terminated)字符串指针更加安全。下面是一个小例子: 
_LIT(KHelloWorld,"Hello World"); 
TBufC<maxBuf> buf; 
buf=KHelloWorld;//设置内容 

TPtr ptr=buf.Des();//取得指向该缓冲器的指针 
ptr[7]='a';//将‘0’变成'a' 

ptr[8]='l';//将‘r’变成'l' 
ptr[9]='e';//将'l'变成‘e’ 

ptr[10]='s';//将‘d’变成‘s’ 

//现在缓冲器的内容为“Hello Wales” 



5、堆缓冲区描述符 
      堆描述符HBufC封装了存储在堆上的、属于该描述符所拥有的数据。由于这些数据是动态分配的,因此通过重新分配堆缓冲器,可以在运行时对描述符的最大长度进行设置很改变。 

      BufC是基于TDesC,并且提供了方法来改变所存储数据的长度(HBufC::ReAlloc()和HBufC::ReAllocL()),以及赋值 操作来设置数据的内容(受限于最大长度,不能超过最大长度)。可以通过使用HBufC::Des()获取可修改指针描述符来修改描述符的内容,下面是一个 小例子: 
_LIT(KHelloWorld,"Hello World!"); 
HBufC *heapBuf=HBufC::NewL(KelloWorld().Length());//声明一个长度为KHelloWorld长的堆描述符 
*heapBuf=KHelloWorld; 

delete heapBuf; 

转换 

描述符之间的转换,如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");
 
TBufC8<50>  buf(KTestStr); 

CCnvCharacterSetConverter
* conv =
 CCnvCharacterSetConverter::NewL(); 

CleanupStack::PushL(conv); 

RFs fs; 
User::LeaveIfError(fs.Connect()); 

if (conv->PrepareToConvertToOrFromL(KCharacterSetIdentifierAscii, fs) !=
 CCnvCharacterSetConverter::EAvailable) 

User::Leave(KErrNotSupported); 


HBufC
* str =
 HBufC::NewL(buf.Length()); 
CleanupStack::PushL(str); 

TPtr ptr 
= str->
Des(); 
TInt state 
=
 CCnvCharacterSetConverter::KStateDefault; 

if (conv->ConvertToUnicode(ptr, buf, state) ==
 CCnvCharacterSetConverter::EErrorIllFormedInput) 

User::Leave(KErrArgument); 


fs.Close(); 
console
->
Write(ptr); 


CleanupStack::PopAndDestroy(2); 

方法 

1、描述符都有的方法: 
  Locate():    定位指定字符的位置; 
  Compare(): 按字节比较两个描述符大小 

  Match():    搜索指定描述符的位置,可使用? *等通配符 
  Find():      搜索指定描述符在当前描述符中第一次出现的位置 

  Left():      提取描述符最左边的数据 

  Right():    提取描述符最右边的数据 

  Mid():        提取描述符中间的位置 
2、只有TPtr和TBuf才有的函数 

  Append():    在描述符后面添加一个字符; 
  LowerCase():将描述符转为小写字母 

  UpperCase():将描述符转为大写字母 
  Insert():在指定位置插入新的描述符 

  Delete():在指定位置删除指定长度个数据项 

3、描述符的典型用法: 
    1、TBuf/TBufC:栈上的小数据量存储 

    2、TPtrC:常量字符串或数据 
    3、TPtr:指向常量字符串或数据,通过Des()方法进行数据修改 

    4、HBufC:大数据量时的处理 
目录
相关文章
|
API 开发工具 C++
API Plug-in for the S60 3rd Edition SDK for Symbian OS, for C++, MR
Package URL: Extensions plug-in package for S60 3rd Edition SDK for Symbian OS, for C++, MRCurrent version: 5.
1054 0
|
API 开发工具 C++
API Plug-in for the S60 3rd Edition SDK for Symbian OS, for C++, supporting Feature Pack 1
Package URL: Extensions plug-in package for S60 3rd Edition SDK for Symbian OS, for C++, supporting Feature Pack 1 Current version: 2.
813 0
|
9月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
158 0
|
5月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
249 0
|
7月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
292 12
|
8月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
173 16
|
9月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
8月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。