LPCTSTR運算子 CString使用注意

2021-04-24 08:58:09 字數 2934 閱讀 8694

cstring類功能強大,比stl的string類有過之無不及.新手使用cstring時,都會被它強大

的功能所吸引.然而由於對它內部機制的不了解,新手在將cstring向c的字元陣列轉換時

容易出現很多問題.因為cstring已經過載了lpctstr運算子,所以cstring類向const

char *轉換時沒有什麼麻煩,如下所示:

char a[100];

cstring str("aaaaaa");

strncpy(a,(lpctstr)str,sizeof(a));

或者如下:

strncpy(a,str,sizeof(a));

以上兩種用法都是正確地.因為strncpy的第二個引數型別為const char *.所以編譯器

會自動將cstring類轉換成const char *.很多人對lpctstr是什麼東西迷惑不解,讓我們

來看看:

1.lp表示長指標,在win16下有長指標(lp)和短指標(p)的區別,而在win32下是沒有區別

的,都是32位.所以這裡的lp和p是等價的.

2.c表示const

3.t是什麼東西呢,我們知道tchar在採用unicode方式編譯時是wchar_t,在普通時編譯成char

那麼就可以看出lpctstr(pctstr)在uincode時是const wchar_t *,pcwstr,lpcwstr,在

多位元組字元模式時是const char *,pcstr,lpcstr.

接下來我們看在非unicode情況下,怎樣將cstring轉換成char *,很多初學者都為了方便

採用如下方法:

(char *)(lpcstr)str.這樣對嗎?我們首先來看乙個例子:

cstring str("aa");

strcpy((char *)(lpctstr)str,"aaaaaaaa");

cout<<(lpctstr)str《在debug下執行出現了異常,我們都知道cstring類內部有自己的字元指標,指向乙個已分

配的字元緩衝區.如果往裡面寫的字元數超出了緩衝區範圍,當然會出現異常.但這個程

序在release版本下不會出現問題.原來對cstring類已經進行了優化.當需要分配的記憶體

小於64位元組時,直接分配64位元組的記憶體,以此類推,一般cstring類字元緩衝區的大小為

64,128,256,512...這樣是為了減少記憶體分配的次數,提高速度.

那有人就說我往裡面寫的字元數不超過它原來的字元數,不就不會出錯了,比如

cstring str("aaaaaaa");

strcpy((char *)(lpctstr)str,"aa");

cout<<(lpctstr)str《這樣看起來是沒什麼問題.我們再來看下面這個例子:

cstring str("aaaaaaa");

strcpy((char *)(lpctstr)str,"aa");

cout<<(lpctstr)str我們看到str的長度沒有隨之改變,繼續為7而不是2.還有更嚴重的問題:

cstring str("aaaaaaa");

cstring str1 = str;

strcpy((char *)(lpctstr)str,"aa");

cout<<(lpctstr)str< cout<<(lpctstr)str1《按說我們只改變了str,str1應該沒有改變呀,可是事實時他們都變成了"aa".難道str和

str1裡面的字元指標指向的緩衝區是乙個.我們在effective c++裡面得知,如果你的類

內部有包含指標,請為你的類寫乙個拷貝建構函式和賦值運算子.不要讓兩個物件內部的

指標指向同一區域,而應該重新分配記憶體.難道是微軟犯了錯?

原來這裡還有乙個"寫時複製"和"引用計數"的概念.cstring類的用途很廣,這樣有可能

在系統內部產生大量的cstring臨時物件.這時為了優化效率,就採用在系統軟體內部廣

泛使用的"寫時複製"概念.即當從乙個cstring產生另乙個cstring並不複製它的字元緩

沖區內容,而只是將字元緩衝區的"引用計數"加1.當需要改寫字元緩衝區內的內容時,才

分配記憶體,並複製內容.以後我會給出乙個"寫時複製"和"引用計數"的例子

我們回到主題上來,當我們需要將cstring轉換成char *時,我們應該怎麼做呢?其時只是

麻煩一點,如下所示:

cstring str("aaaaaaa");

strcpy(str.getbuffer(10),"aa");

str.releasebuffer();

當我們需要字元陣列時呼叫getbuffer(int n),其中n為我們需要的字元陣列的長度.使

用完成後一定要馬上呼叫releasebuffer();

還有很重要的一點就是,在能使用const char *的地方,就不要使用char *

指定 cstring 形參

對於大多數需要字串引數的函式,最好將函式原型中的形參指定為乙個指向字元 (lpctstr) 而非 cstring 的 const 指標。當將形參指定為指向字元的 const 指標時,可將指標傳遞到 tchar 陣列(如字串 ["hi there"])或傳遞到 cstring 物件。cstring 物件將自動轉換成 lpctstr。任何能夠使用 lpctstr 的地方也能夠使用 cstring 物件。

如果某個形參將不會被修改,則也將該引數指定為常數字串引用(即 const cstring&)。如果函式要修改該字串,則刪除 const 修飾符。如果需要預設為空值,則將其初始化為空字串 [""],如下所示:

void addcustomer( const cstring& name, const cstring& address, const cstring& comment = "" );

對於大多數函式結果,按值返回 cstring 物件即可。

(運算子) 運算子

運算子既可作為一元運算子也可作為二元運算子。備註 unsafe context data guid 00bf87717d88a9fac1afadb796c675da 一元 運算子返回運算元的位址 要求 unsafe 上下文 bool data guid 9efd189df2cfb88799dca08...

JS運算子 算術運算子 比較運算子 賦值運算子

兩邊的變數都是number型別 則是單純的加法運算 當字串出現時 結果是字串型別 字串之後的內容 不論什麼型別 都會被作為字串進行拼接 例子 var num1 10 var num2 20 num num1 num2 var result num1 num2 num1 false console.l...

NOT運算子與 運算子

6.4.2 not運算子與 運算子 對於簡單的條件查詢,not運算子與 運算子的功能幾乎沒有什麼區別,那麼not運算子的優勢體現在 呢?答案是它可以與其他運算子組合使用,這一點是 運算子所不能實現的。在6.4.1節已經介紹了not運算子與in運算子組合使用的例子,下面給出乙個not運算子與betwe...