CString類功能強(qiáng)大,比STL的string類有過之無(wú)不及.新手使用CString時(shí),都會(huì)被它強(qiáng)大的功能所吸引.然而由于對(duì)它內(nèi)部機(jī)制的不了解,新手在將CString向C的字符數(shù)組轉(zhuǎn)換時(shí)容易出現(xiàn)很多問題.因?yàn)镃String已經(jīng)重載了LPCTSTR運(yùn)算符,所以CString類向const char *轉(zhuǎn)換時(shí)沒有什么麻煩,如下所示:
char a[100]; CString str("aaaaaa"); strncpy(a,(LPCTSTR)str,sizeof(a)); 或者如下: strncpy(a,str,sizeof(a)); 以上兩種用法都是正確地.因?yàn)閟trncpy的第二個(gè)參數(shù)類型為const char *.所以編譯器會(huì)自動(dòng)將CString類轉(zhuǎn)換成const char *.很多人對(duì)LPCTSTR是什么東西迷惑不解,讓我們來(lái)看看: 1.LP表示長(zhǎng)指針,在win16下有長(zhǎng)指針(LP)和短指針(P)的區(qū)別,而在win32下是沒有區(qū)別的,都是32位.所以這里的LP和P是等價(jià)的. 2.C表示const 3.T是什么東西呢,我們知道TCHAR在采用UNICODE方式編譯時(shí)是wchar_t,在普通時(shí)編譯成char那么就可以看出LPCTSTR(PCTSTR)在UINCODE時(shí)是const wchar_t *,PCWSTR,LPCWSTR,在多字節(jié)字符模式時(shí)是const char *, PCSTR,LPCSTR.接下來(lái)我們看在非UNICODE情況下,怎樣將CString轉(zhuǎn)換成char *,很多初學(xué)者都為了方便采用如下方法: (char *)(LPCSTR)str 這樣對(duì)嗎?我們首先來(lái)看一個(gè)例子: CString str("aa"); strcpy((char *)(LPCTSTR)str,"aaaaaaaa"); cout<<(LPCTSTR)str< 在Debug下運(yùn)行出現(xiàn)了異常,我們都知道CString類內(nèi)部有自己的字符指針,指向一個(gè)已分配的字符緩沖區(qū).如果往里面寫的字符數(shù)超出了緩沖區(qū)范圍,當(dāng)然會(huì)出現(xiàn)異常.但這個(gè)程序在Release版本下不會(huì)出現(xiàn)問題.原來(lái)對(duì)CString類已經(jīng)進(jìn)行了優(yōu)化.當(dāng)需要分配的內(nèi)存小于64字節(jié)時(shí),直接分配64字節(jié)的內(nèi)存,以此類推,一般CString類字符緩沖區(qū)的大小為64,128,256,512...這樣是為了減少內(nèi)存分配的次數(shù),提高速度. 那有人就說(shuō)我往里面寫的字符數(shù)不超過它原來(lái)的字符數(shù),不就不會(huì)出錯(cuò)了,比如 CString str("aaaaaaa"); strcpy((char *)(LPCTSTR)str,"aa"); cout<<(LPCTSTR)str< 這樣看起來(lái)是沒什么問題.我們?cè)賮?lái)看下面這個(gè)例子: CString str("aaaaaaa"); strcpy((char *)(LPCTSTR)str,"aa"); cout<<(LPCTSTR)str< 我們看到str的長(zhǎng)度沒有隨之改變,繼續(xù)為7而不是2.還有更嚴(yán)重的問題: CString str("aaaaaaa"); CString str1 = str; strcpy((char *)(LPCTSTR)str,"aa"); cout<<(LPCTSTR)str< 按說(shuō)我們只改變了str,str1應(yīng)該沒有改變呀,可是事實(shí)時(shí)他們都變成了"aa".難道str和str1里面的字符指針指向的緩沖區(qū)是一個(gè).我們?cè)贓ffective C++里面得知,如果你的類內(nèi)部有包含指針,請(qǐng)為你的類寫一個(gè)拷貝構(gòu)造函數(shù)和賦值運(yùn)算符.不要讓兩個(gè)對(duì)象內(nèi)部的指針指向同一區(qū)域,而應(yīng)該重新分配內(nèi)存.難道是微軟犯了錯(cuò)? 原來(lái)這里還有一個(gè)"寫時(shí)復(fù)制"和"引用計(jì)數(shù)"的概念.CString類的用途很廣,這樣有可能在系統(tǒng)內(nèi)部產(chǎn)生大量的CString臨時(shí)對(duì)象.這時(shí)為了優(yōu)化效率,就采用在系統(tǒng)軟件內(nèi)部廣泛使用的"寫時(shí)復(fù)制"概念.即當(dāng)從一個(gè)CString產(chǎn)生另一個(gè)CString并不復(fù)制它的字符緩沖區(qū)內(nèi)容,而只是將字符緩沖區(qū)的"引用計(jì)數(shù)"加1.當(dāng)需要改寫字符緩沖區(qū)內(nèi)的內(nèi)容時(shí),才分配內(nèi)存,并復(fù)制內(nèi)容.以后我會(huì)給出一個(gè)"寫時(shí)復(fù)制"和"引用計(jì)數(shù)"的例子我們回到主題上來(lái),當(dāng)我們需要將CString轉(zhuǎn)換成char *時(shí),我們應(yīng)該怎么做呢?其時(shí)只是麻煩一點(diǎn),如下所示: CString str("aaaaaaa"); strcpy(str.GetBuffer(10),"aa"); str.ReleaseBuffer(); 當(dāng)我們需要字符數(shù)組時(shí)調(diào)用GetBuffer(int n),其中n為我們需要的字符數(shù)組的長(zhǎng)度.使用完成后一定要馬上調(diào)用ReleaseBuffer();還有很重要的一點(diǎn)就是,在能使用const char *的地方,就不要使用char * |
|