1、定義
CString::GetBuffer有兩個重載版本:
(1)LPTSTR GetBuffer( );
(2)LPTSTRGetBuffer( int nMinBufLength );throw( CMemoryException );
調用第二個版本中,當設定的長度nMinBufLength小于原字元串長度nOldLen時,nMinBufLength預設等于原來字元串長度nOldLen,是以該參數會被忽略,不配置設定記憶體,指向原CString;當設定的長度大于原字元串本身的長度時就要重新配置設定(reallocate)一塊比較大的空間出來。而調用第一個版本時,直接當做nMinBufLength=0。注意:nMinBufLength不包含最後結束的空字元。
參考:http://msdn.microsoft.com/en-us/library/aa314880(v=vs.60).aspx
2、作用
GetBuffer(int nMinBufLength)是用來傳回一個你所指定大小可寫記憶體的成員方法。它和被重載的操作符LPCTSTR還是有點本質差別的,LPCTSTR是直接傳回一個隻讀記憶體的指針,而GetBuffer則是傳回一個可以供調用者寫入的記憶體,并且你可以給定大小。例如:
CString s("abcd");
LPTSTR p = s.GetBuffer( 10 );
strcpy( (char*)p, "Hello" ); // directly access CString buffer
s.ReleaseBuffer( );
cout << "CString s = "<< s ; //在多位元組字元集_MBCS下面輸出Hello
3、與ReleaseBuffer的結合使用
GetBuffer()主要作用是将字元串的緩沖區長度鎖定,ReleaseBuffer則是解除鎖定,使得CString對象在以後的代碼中繼續可以實作長度自适應增長的功能。
至于是否需要在GetBufer後面調用ReleaseBuffer(),是根據你的後面的程式是否需要繼續使用該字元串變量,并且是否動态改變其長度而定的。如果你GetBuffer以後程式自函數就退出,局部變量都不存在了,調用不調用ReleaseBuffer沒什麼意義了;如果需要繼續使用該字元串變量,則需要在使用之前調用ReleaseBuffer。
舉個例子:
int readFile(CString& str, const CString& strPathName)
{
FILE* fp = fopen(strPathName, "r"); // 打開檔案
fseek(fp, 0, SEEK_END); //指向檔案尾部
int nLen = ftell(fp); //獲得檔案長度
fseek(fp, 0, SEEK_SET); //重置讀指針
char* psz = str.GetBuffer(nLen); //配置設定足夠記憶體
fread(psz, sizeof(char), nLen, fp); //讀檔案内容并寫入str
str.ReleaseBuffer(); //千萬不能缺少
fclose(fp);
}
上面的函數是GetBuffer函數最典型的用法了,其實它就相當于申請一塊nLen大小的記憶體,隻不過,這塊記憶體是被引用在CString對象的内部而已,這是非常有效的一種用法,如果不直接用GetBuffer函數來申請的話,那麼你必須用new操作符(或者malloc()函數)在CString的外部申請,然後再将申請的記憶體拷貝到CString對象中,顯然這是一個非常備援的操作,會使你函數的效率大大下降。
ReleaseBuffer函數是用來告訴CString對象,你的GetBuffer所引用的記憶體已經使用完畢,現在必須對它進行封口,否則 CString将不會知道它現在所包含的字元串的長度,是以在使用完GetBuffer之後,必須立即調用ReleaseBuffer函數重置 CString的内部屬性,其實也就是頭部資訊。