CString剖析與詳解

2021-04-19 20:57:35 字數 2344 閱讀 7223

1 cstring實現的機制

cstring是通過「引用」來管理串的,象window核心物件、com物件等都是通過引用來實現的。而cstring也是通過這樣的機制來管理分配的記憶體塊。實際上cstring物件只有乙個指標成員變數,所以任何cstring例項的長度只有4位元組.

正因為如此,乙個這樣的記憶體塊可被多個cstring所引用.

怎麼知道有多少個cstring引用它呢?同樣,它也會記錄一些資訊。如被引用數,串長度,分配記憶體長度。

這塊引用記憶體塊的結構定義如下:

struct cstringdata ;

由於有了這些資訊,cstring就能正確地分配、管理、釋放引用記憶體塊。

如果你想在除錯程式的時候獲得這些資訊。可以在watch視窗鍵入下列表示式:(cstringdata*)((cstringdata*)(this->m_pchdata)-1)或(cstringdata*)((cstringdata*)(str.m_pchdata)-1)//str為指cstring例項

正因為採用了這樣的好機制,使得cstring在大量拷貝時,不僅效率高,而且分配記憶體少。

2.lpctstr 與 getbuffer(int nminbuflength)

這兩個函式提供了與標準c的相容轉換。這兩個函式實際上返回的都是指標.

(1) lpctstr 它的執行過程其實很簡單,只是返回引用記憶體塊的串位址。它是作為操作符過載提供的,所以在**中有時可以隱式轉換,而有時卻需強制轉製。如:

cstring str;

const char* p = (lpctstr)str;

//假設有這樣的乙個函式,test(const char* p);你就可以這樣呼叫

test(str);//這裡會隱式轉換為lpctstr

(2) getbuffer(int nminbuflength) 它類似,也會返回乙個指標,不過它有點差別,返回的是lptstr

(3)兩者本質上完全不一樣,一般說lpctstr轉換後只應該當常量使用,或者做函式的入參;而getbuffer(...)取出指標後,可以通過這個指標來修改裡面的內容,或者做函式的出參。

(4) 不過這裡還有一點注意事項:就是str.getbuffer(20)後,str的分配長度為20,即指標p它所指向的buffer只有20位元組長,給它賦值時,切不可超過,否則災難離你不遠了;如果指定長度小於原來串長度,如getbuffer(1),實際上它會分配4個位元組長度(即原來串長度);另外,當呼叫getbuffer(...)後並改變其內容,一定要記得呼叫releasebuffer(),這個函式會根據串內容來更新引用記憶體塊的頭部資訊。

3.拷貝 & 賦值 & "引用記憶體塊" 的釋放

cstring雖然可以多個物件指向同一引用內塊存,但是它們在進行各種拷貝、賦值及改變串內容時,它的處理是很智慧型並且非常安全的,完全做到了互不干涉、互不影響。當然必須要求你的**使用正確恰當,特別是實際使用中會有更複雜的情況,如做函式引數、引用、及有時需儲存到cstringlist當中,如果哪怕有一小塊地方使用不當,其結果也會導致發生不可預知的錯誤.例如:

void test()

//由於d生命結束,呼叫析構函式,導至引用計數減1(引用記憶體塊的引用計數為2,長度為4,分配長度為4)

lptstr temp = a.getbuffer(10);

//此語句也會導致重新分配新記憶體塊。temp指向新分配引用記憶體塊的串首位址(新分配的引用記憶體塊的引用計數為1,長度為0,分配長度為10)

//同時原引用記憶體塊引用計數減1. 只有str仍 指向原引用記憶體塊(引用記憶體塊的引用計數為1, 長度為4, 分配長度為4)

strcpy(temp, "temp");

//a指向的引用記憶體塊的引用計數為1,長度為0,分配長度為10 a.releasebuffer();//注意:a指向的引用記憶體塊的引用計數為1,長度為4,分配長度為10 }

//執行到此,所有的區域性變數生命週期都已結束。物件str a b 各自呼叫自己的析構構

//函式,所指向的引用記憶體塊也相應減1

4 重要的函式

freeextra() 會釋放所分配的多餘的記憶體。

format(...) 與 formatv(...)

實際上sprintf(...)怎麼用,它就怎麼用。使用時需注意一點:就是它的引數的特殊性,由於編譯器在編譯時並不能去校驗格式串引數與對應的變元的型別及長度。所以必須注意,兩者一定要對應上,否則就會出錯。

allocsysstring()與setsysstring(bstr*)

這兩個函式提供了串與bstr的轉換。使用時須注意:當呼叫allocsysstring()後,須呼叫它sysfreestring(...) .

C string類的詳解

from 之所以拋棄char 的字串而選用c 標準程式庫中的string類,是因為他和前者比較起來,不必擔心記憶體是否足夠 字串長度等等,而且作為乙個泛型類出現,他整合的操作函式足以完成我們大多數情況下 甚至是100 的需要。我們可以用 進行賦值操作,進行比較,做串聯 是不是很簡單?我們盡可以把它看...

C string庫函式詳解

連線字串 字串賦值 字串比較 例如a b,aa ab 比較字串 輸出 輸入字串 注意 使用過載的運算子 時,必須保證前兩個運算元至少有乙個為 string 型別。例如,下面的寫法是不合法的 1 include 2 include 3int main 42.1 find 查詢函式 1 str.find...

C String詳解 小白專用

include string string s hello world char temp hello world string s temp string s hello world char temp char s.c str 此處一定要加強制型別轉化,c str 返回的是乙個臨時指標,不能對其...