CString之GetBuffer與ReleaseBuffer

weixin_34088583發表於2016-11-09

  我們知道,CString是MFC中提供的方便字串操作的一個類,非常好使,具有自動動態記憶體管理功能。

  GetBuffer()主要作用是將字串的緩衝區長度鎖定;

  ReleaseBuffer()則是解除對緩衝區的鎖定,這樣使得CString物件在以後的程式碼中繼續可以實現長度自適應增長的功能。

  

  GetBuffer()說白了就兩個功能:

  1:就是將CString裡面的記憶體交到外部一個來處理,外部可以直接修改它的內容。

  2:重新修改CString的記憶體大小,這個數值不包含null結尾符。

  另一個典型的用法:就是將CString裡面的內容變為int或long型,需要先獲取裡面的記憶體指標。這樣就可以先GetBuffer(記憶體大小)方便直接轉換。

  如果在外部修改了CString裡面的內容,在重新使用CString之前,需呼叫ReleaseBuffer()也就是說,ReleaseBuffer()不需要每次都呼叫。

 

  CString::GetBuffer有兩個過載版本:

  LPTSTR GetBuffer( );

  LPTSTR GetBuffer(int nMinBufferLength);

  在第二個版本中,當設定的長度小於原字串長度時,nMinBufLength = nOldLen,該引數會被忽略,不分配記憶體,指向原CString;當設定的長度大於原字串本身的長度時就要重新分配(reallocate)一塊比較大的空間出來。

  而呼叫第一個版本時,應如通過傳入0來呼叫第二個版本一樣。

 

  是否需要在GetBufer()後面呼叫ReleaseBuffer(),是根據你的後面的程式是否需要繼續使用該字串變數,並且是否動態改變其長度而定的。

  如果你GetBuffer()以後程式自函式就退出,區域性變數都不存在了,呼叫不呼叫ReleaseBuffer()沒什麼意義了。


     GetBuffer(int size)是用來返回一個你所指定大小可寫記憶體的成員方法。它和被過載的操作符LPCTSTR還是有點本質區別的,LPCTSTR是直接返回一個只讀記憶體的指標,而GetBuffer則是返回一個可以供呼叫者寫入的記憶體,並且,你可以給定大小。

  下面是個簡單的,但也是非常典型的例子:

 1 int readFile(CString& str, const CString& strPathName)
 2 {
 3       FILE* fp = fopen(strPathName, "r");
 4       fseek(fp, 0, SEEK_END);
 5       int nLen = ftell(fp); 
 6       fseek(fp, 0, SEEK_SET); 
 7       char* psz = str.GetBuffer(nLen);
 8       fread(psz, sizeof(char), nLen, fp); 
 9       str.ReleaseBuffer();
10       fclose(fp);
11 }

  上面的函式是GetBuffer()函式最典型的用法了,其實它就相當於申請一塊nLen大小的記憶體,只不過,這塊記憶體是被引用在CString物件的內部而已,這是非常有效的一種用法,如果不直接用GetBuffer函式來申請的話,那麼你必須用new操作符(或者malloc()函式)在CString的外部申請,然後再將申請的記憶體拷貝到CString物件中,顯然這是一個非常冗餘的操作,會使你函式的效率大大下降。
  ReleaseBuffer()函式是用來告訴CString物件,你的GetBuffer()所引用的記憶體已經使用完畢,現在必須對它進行封口,否則 CString將不會知道它現在所包含的字串的長度,所以在使用完GetBuffer()之後,必須立即呼叫ReleaseBuffer()函式重置CString的內部屬性,其實也就是頭部資訊。

相關文章