// -----------------------------------------------------------------
//
// 這是我的第二篇博文,開始學習Symbian c++
// 同大家一起努力
// 謹以此文獻給我的最愛 YY女孩(YY 可別想壞了哦)
//
// -----------------------------------------------------------------
每一個初學Symbian c++的同學肯定和我一樣迷茫,那我們就一起來學習吧!
我用的環境是Carbide c++V2.0
其實個人認爲Symbian最難入門的是那些從來沒見過的數據類型,非常頭痛,下面是我找到的數據類型
表2-1 Symbian OS的基本數據類型
(發現下面這些數據都是T開頭的,對了學習SC++,對考都和結尾要留心)
數 據 類 型 |
描 述 |
C++內置類型 |
TInt |
有符號整數。在所有實現中保證數據至少爲32位 |
signed int |
TUint |
無符號整數。在所有實現中保證數據至少爲32位 |
unsigned int |
TInt32、TInt16、 |
32位、16位和8位的有符號整數 |
long int、short int、singed char |
|
|
|
TUint32、TUint16 TUint8 |
32位、16位和8位的無符號整數 |
unsigned long int、unsigned short int、unsigned char |
TInt64 |
64位整數 |
long long |
TUint64 |
64位無符號整數 |
unsigned long long |
TText |
文本型,又細分爲TText8和TText16,內部引用都是TText16 |
unsigned short int |
TText8 TText16 |
8位和16位無符號文本 |
unsigned short int unsigned char |
TReal32 |
32位浮點數 |
float |
TReal、TReal64 |
64位浮點數 |
double |
TBool |
布爾型 |
int (這裏是Int ?) |
TAny |
指針型 |
void |
如果想了解更仔細請參考 http://book.csdn.net/bookfiles/1240/100124036909.shtml
除了以上的基本數據類型,SC++中的String型也是攔路虎之一;
描述符 SC++中的String型
描述符是 Symbian OS中用到的字符串類。之所以這樣稱呼它們,是因爲它們是自描述的字符串。也就是說,描述符不僅包含它所描述的字符串數據的長度,還包含了類型信息,以區分描述符數據在內存中不同的結構。描述符可以防止緩存溢出,它並不使用NULL結束符作爲字符串的結尾。(這個也是c++的特點,C中纔會有NULL來結束)
描述符的應用從最底層向上貫穿於整個操作系統,而且它們被設計得非常有效率,使用最小的內存空間但又足夠存儲數據,並同時可以全面描述其長度和位置。描述符可作爲字符串幷包含字符數據。同時它們還可以用來操作二進制數據,因爲它們不需要用NULL作爲結尾字符來確定長度。
表3-2 對描述符類型的總結
名 稱 |
是否可修改 |
等 價 C |
類 型 |
說 明 |
TDesC |
否 |
n/a |
不可實例化 |
其他所有描述符的基類(字面描述符除外) |
TDes |
是 |
n/a |
不可實例化 |
所有可修改描述符的基類 |
TPtrC |
否 |
const char* (數據不被描述符所 “擁有”) |
指針 |
數據與描述符是分開存儲的,即描述符並不知道數據的存儲位置 |
TPtr |
是 |
char * (數據不被描述符所 “擁有”) |
指針 |
數據與描述符是分開存儲的,即描述符並不知道數據的存儲位置 |
TBufC |
可間接修改 |
const char[] |
棧緩存 |
瘦模板的大小在編譯時才確定 |
TBuf |
是 |
const[] |
棧緩存 |
瘦模板的大小在編譯時才確定 |
HBufC |
可間接修改 |
const char* (可“擁有”數據) |
堆緩存 |
用於修改頻繁的動態數據存儲 |
RBuf |
是 |
char* (可“擁有”數據) |
堆緩存 |
用於可修改的動態數據存儲 |
TLitC |
否 |
static const char[] |
字面描述符 |
構建在ROM裏 |
TDes定義了一組操作可變字符串數據的方法,包括那些對描述符進行擴充、填充以及格式化的操作。所有改變描述符的操作代碼都由TDes來實現,並且可被其派生類繼承。在Symbian Developer Library(這個書友誰可以給個連下載下,謝謝)裏有對可變及不可變描述符的基類API方法進行全面描述的相關文檔。
描述符基類TDesC和TDes實現了所有通用的描述符操作代碼,但是它們不能被實例化。
指針型描述符:TPtrC和TPtr
覺得沒什麼好講的,就是指針型,沒能擁有真的內存空間,末尾是C的是常量指針,不能修改指向的內容,但是可以修改指針的指向,而TPtr是沒有限制的,可以改變指向的內存地址的數據。
基於棧緩存的描述符TBufC和TBuf 在上面的表中已有說明,相當於數組
動態描述符:HBufC和RBuf
HBufC和RBuf描述符類可用於在編譯期間大小不能確定的動態字符串數據(比如網絡接收數據),以及那些對棧內存來說過於龐大的數據。這些類被用於在C中需要使用malloc來分配數據的地方。
HBufC
類HBufC8和HBufC16(其對應的中立類 HBufC被typedef定義爲HBufC16)提供了一組靜態的NewL()函數,以便在堆上創建描述符。這些方法在沒有足夠內存可用的情況下會異常退出。所有的堆緩存必須使用這些方法來建立,或者也可以使用TdesC類的Alloc()或AllocL()方法來建立,這兩個方法都可以從已存在的描述符中建立出HBufC的一個副本。一旦描述符以其所需的大小建立後,當它又需要更多空間時就不會自動重新分配大小,額外的內存需要使用ReAlloc() 或ReAllocL()方法來分配。
作爲一個類名中以C字符爲後綴的類,HBufC描述符不能被直接改變,但此類提供的賦值操作符允許替換緩存中的整個內容。要想在運行期間改變一個HBufC對象,應該首先從HBufC::Des()方法中獲得一個可變的描述符指針TPtr。
_LIT(KTestBuffer, "Heap Based");
(這個是個內置類型,相當於#Define KTestBuffer “Heap Based“)
// create a heap-based descriptor and place it on cleanup stack
HBufC* pHeap = HBufC::NewLC(32);
// create a pointer descriptor around pHeap
TPtr ptr(pHeap->Des());//把值賦給指針
// modify pHeap indirectly via ptr
ptr = KTestBuffer; //這裏有點費解,KTestBuffer難道也是指針?
...
// clean up
CleanupStack::PopAndDestroy(pHeap);
RBuf
RBuf類從TDes繼承而來,所以RBuf類的對象可以不用創建一個指向其數據的TPtr以修改其內容,這使得它要比HBufC更好用。在實例化時,RBuf對象既可以自己分配緩存,也可以取得先前分配好的內存或已有的堆描述符的控制權。爲了與本章開始時的Symbian OS命名習慣保持一致,RBuf類沒有被叫做HBufC,因爲與HBufC不同的是,RBuf不是直接在堆上創建的。RBuf描述符通常在棧上創建,並且擁有一個它需要負責清除的指向堆上資源的指針。
在內部,RBuf表現爲以下兩種方式之一:
● 與TPtr直接指向內存中存儲的描述符數據類似,RBuf對象分配或取得描述符數據的擁有權。
● 作爲一個指向已存在堆描述符的指針——HBufC*。RBuf對象取得HBufC的擁有權,並且擁有一個指向包含完整描述符對象的指針(完整是相對於前面所講的指向一個簡單數據塊的指針而言的)。
然而這都是透明的,不需要去了解一個特定的RBuf對象在內部是怎麼描述的。使用此描述符類也相當直觀,就像使用其他的描述符類一樣,使用從TDes和TDesC繼承而來的方法即可。
RBuf對於Symbian OS來說加入的時間相對較短,它最先出現在Symbian OS v8.1的文檔中,並且被廣泛應用於爲基於Symbian OS v9或其後版本的手機所設計的軟件中。
RBuf在許多最初的例子代碼中基本沒有用到,但是它卻是您在需要爲容納經常改變的數據而動態分配緩存時比起 HBufC來說更爲容易的類。
HBufC對於那些需要爲容納不會改變的數據而動態分配的描述符來說還是相當理想的;也就是說如果是不改變數據的訪問的話,它還是不錯的。
使用RBuf
RBuf對象可以通過Create()、CreateMax()或CreateL()方法來創建,並可以指定所能存儲的描述符數據的最大長度。也可以先實例化一個RBuf,然後將另一個描述符的內容複製進去,如下所示:
RBuf myRBuf;
LIT(KHelloRBuf, "Hello RBuf!"); // Literal descriptor
myRBuf.CreateL(KHelloRBuf());
CreateL()爲RBuf分配了一段緩存來引用。如果RBuf之前擁有一段緩存,由於CreateL()在分配新的緩存引用前不會將其清除,所以必須先調用Close()來釋放先前擁有的內存。
另一種方法是先實例化RBuf,然後再用Assign()方法取得一段已存在內存的所有權。
// Taking ownership of HBufC
HBufC* myHBufC = HBufC::NewL(20);
RBuf myRBuf;
myRBuf.Assign(myHBufC);
Assign()也會使RBuf已經擁有的數據孤立,所以在重新指定之前要調用Close()來避免內存泄漏。
在特定操作需要更多內存時,RBuf類不會去操縱緩存的大小或者爲它重新分配內存。如果一個可變的方法——比如Append()——在沒有足夠可用內存時被RBuf對象調用,那麼將會出現一個嚴重錯誤。作爲程序員,您應該爲保證RBuf對象在其緩存內有足夠空間而負責,並可以在需要時使用ReAllocL()方法:
// myRBuf is the buffer to be resized e.g. for an Append() operation
myRBuf.CleanupClosePushL(); // push onto cleanup stack for leave-safety
myRBuf.ReAllocL(newLength); // extend to newLength
CleanupStack::Pop(); // remove from cleanup stack
注意上面的例子用到了CleanupClosePushL(),來把RBuf類推入清除棧。清除工作在調用Close()(或者是調用CleanupStack::PopAndDestroy(),當RBuf是通過調用RBuf::
Cleanup-ClosePushL()被推入清除棧時)時開始,這對於其他R類來說很常見。
字面描述符
字面描述符與其他描述符類型略有不同。它們相當於C 中的static const char[],並且由於它們是常量,所以可以被構建在ROM裏以便在運行時節省內存。一組e32def.h中的宏可以用來定義Symbian OS的兩種不同類型的字面文字,_LIT和_L。
因爲更具效率,所以_LIT宏更適合用作Symbian OS的字面文字。它的典型用法如下:
_LIT(KSymbianOS, "Symbian OS");(注意 K開頭一般都是常量)
_LIT宏在程序的二進制代碼中構建了一個名爲KSymbianOS的TLitC16類型的對象,存儲了相應的字符串(本例中是“Symbian OS”)。顯式的宏定義_LIT8和_LIT16行爲相似,不過_LIT8構建的是TLitC8類型的窄字符串。
TLitC8和TLitC16不是從TDesC8和TDesC16繼承而來的,但是它們擁有和TBufC8及TBufC16相同的二進制佈局。這就保證了所有可以傳入TDesC的地方也可以使用這些類型的對象。
Symbian OS還定義了表示空字符串的字面文字。有三種不同的null描述符,定義如下:
// Build independent:
_LIT(KNULLDesC,"");
// 8-bit for narrow strings:
_LIT8(KNULLDesC8,"");
// 16-bit for Unicode strings:
_LIT16(KNULLDesC16,"");
雖然在測試代碼中(其對內存的使用稍微寬鬆些)還有可能用到_L宏,但是在產品代碼中已經不推薦使用它了。它可以在如下所示的一行代碼裏定義並使用:
TBuf<10> KSymbianBuf(_L("Symbian OS"));
如有錯誤 請斧正 諒解 博文完