2009/08/26

[CB6] AnsiString 類別介紹

以下也是轉載而來的內容,來源是:
AnsiString

全文如下:
AnsiString 其實是一個類(class),不過,它並不歸屬於VCL的框架,不是派生於TObject. 該類封裝了C,C++裏字串的大多操作,並有所發展。方便了C++程式師在程式中使用字串。下面挑典型和重要的說。

一、String就是AnsiString.typedef AnsiString String;

二;在VCL,幾乎所有字串都是AnsiString。若是屬性,則有要求, += 的重載對屬性不保證一定起作用。


Form1->Caption = "窗口標題"; //OK
Form1->Caption += " - 世界你好"; //Err
Form1->Caption = Form1->Caption + " - 世界你好"; //OK

同樣的事情發生 >>(移出) 或 << (移入) 重載上。如字元:
this->Font->Style >> fsBold; //不行的

三、如果要用空串,最好不用 "";

而是:AnsiString emptyStr = *NullStr;
四、現在你不用(顯式地)?字串管理記憶體了:
AnsiString name = "Mike";
ShowMessage(name); //顯示Mike
name = "張三";
ShowMessage(name); //顯示張三
AnsiString name2 = name;
name = 李四";
ShowMessage(name);
ShowMessage(name2);
AnsiString twoName = name + name2;
ShowMessage(twoName);

上面其實說明了,AnsiString 重載了 = 和 + 操作符,讓我們可以直接通過簡單的=或+操作,來賦值,改變一個字串。
如果不用Ansistring這樣或類似的而在C,C++,同樣的操作將是類似於(並不一定和上面完全一致的過程):
char* name = "Make";
ShowMessage(name);
name = new char[strlen("張三") + 1];
stcpy(name, "張三");
ShowMessage(name);
char* name2 = new char [strlen(name1)+1);
strcpy(name2,name);
delete[] name;
name = new char[strlem("李四")+1];
strcpy(name,"李四");
ShowMessage(name);
ShowMessage(name2);
char* twoName = new char [strlen(name) + strlen(name2) + 1)];
strcpy(twoName,name);
strcat(twoName,name2);
ShowMessage(twoName);
delete[] twoName;
delete[] name2;
delete[] name;

肯定可以看出後者在記憶體管理(初始分配,擴容,連接,釋放)上的一堆瑣事。當然,可以考慮用純C的 malloc,realloc, free ,及 sprintf連減少一些操作,但在C++世界裏,這樣的記憶體管理會和使用new,new[] , delete,delete[]的代碼在交接上?生問題。並不是C++程式師的首選。

可能還會說,我就是原意累點,可是直接寫記憶體管理,會帶來高效率啊。。這是不知量力。由於字串管理在一個程式中的使用率太高了,事實上不管是VC的CString, 還是STL的string,或者是C#的string,及我們這裏的AnsiString,統統採用記憶體池,及“realloc on modify(在修改時才生分配記憶體)”等技術,可謂既提高了連續記憶體使用率,又提高了運行速度,這類高級功能,不是一般你我有精力甚至能力去實現。

四、小心,AnsiString 帶有Pascal風格。

AnsiString這個類也重載 [] 操作符 ,用於得到字串中指定的字元,可是,雖然AnsiString純是用C++寫成,但它是?了實現Object Pascal內置類型string,所以必須和Object Pascal保持相容,所以,它的下標也是從1開始:
AnsiString pascal = "Pascal";
char c = pascal[1]; // c 是 'P'

五、可以得到C風格的字串。

Windows在編程介面上還是非面向物件,(等.Net完全取代後,就是了) 它的API還得用到很多的C風格的字串(上面我們舉例的那個);再者,C++既然說完全相容C,那我們難免有時還會喜歡用用C的函數庫。
AnsiString s = "123456";
int len = strlen(s.c_str());
沒錯, c_str() 這個成員函數返回的是一個 const char* 常量字串指標。因?是const的,所以用在類似strlen()這樣僅要求是const char* 的函數還算方便,如果你想安全一點,或者人家函數指定就不能是const ,那你只好複製走:
AnsiString s = "123456";
char* tmp = new char[7];
strcpy(tmp, s.c_str()); //複製
然後對tmp愛幹嘛幹嘛去。

六、它有好多字串操作成員函數,並一般都有對應的同名全局函數。

比如取長度:
AnsiString s = "Hello!";
int len = s.Length(); //求長度
但你也可以這樣:
int len = Length(s);
或例如求子串:
string subString = s.SubString(2,3);
ShowMessage(subString) // "ell"
同樣用個全局的SubString(s,2,3);
注意了,索引從1開始。

沒有留言:

張貼留言