天天看點

CString的GetBuffer函數詳解

 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的内部屬性,其實也就是頭部資訊。

繼續閱讀