自從接觸到Symbian C++的描述符之後才發現在.NET中使用string是一件多麼幸福的事情,雖然Symbian c++難的不僅僅是描述符,下面對其進行簡單整理讓後來者不至於那麼暈。
一、概念-什麼是描述符?
1、描述符是Symbian C++字串的描述類,不同於string,它既可以表示字串,也可以表示位元據;
2、同時支援8位和16位,但是用來儲存字串時並不需要指定哪種類型 ,而是由編譯時間的設定決定
#if defined(_UNICODE)
typedef TPtrC16 TPtrC
else
typedef TPtrC8 TPtrC
但當它用來儲存位元據時通常使用8位版本。
二、細說描述符的類型
簡單地說,描述符可以分為五大類,分別是抽象描述符、文字描述符、緩衝區描述符、指標描述符和堆緩衝區描述符。它們的特點和適用情境都各不相同,下面進行一一介紹。
1、抽象描述符
抽象描述符包含TDesC和TDes,TDes是從TDes派生的,因為這些類是抽象的,所以不能執行個體化,它們多數用於函數參數。TDesC是所有描述符的基類,而TDes與TDesC不同的是TDes可以對資料進行修改,並引入資料最大長度的概念。因為它是所有描述符的基類,因此,後面在描述其他描述符的同時會對它的功能進行介紹。
2、文字描述符
文字描述符是我們用的比較多,它主要用來儲存字串常量,如下:
_LIT(KHelloWorld,"Hello World!");
當使用_LIT()宏的時候,產生的其實是一個TLitC對象(8位或16位),資料實際上被儲存在裝載到RAM的二進位應用程式內,雖然它們實際上並不儲存在ROM(或與ROM類似的快閃記憶體)中,所以可以把它們看成是唯讀。
可以使用()操作符將描述符轉換成常量的TDesC對象,比如:
TInt length=KHelloWorld().Length()
3、緩衝區描述符
緩衝區描述符TBufC和TBuf將它們的資料存放區為本身的一部分,既然該描述符使用在編譯時間就確定的固定數量的記憶體,因此可以在棧上對其進行聲明(作為局部或者成員變數),這裡看個小例子。
_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、指標描述符
指標描述符TPtrC和TPtr用於引用儲存在別處的、不屬於該描述符所擁有的資料。使用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;
三、幾種描述符總結
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:大資料量時的處理