在此,我個人認為:CString封裝得確實很完美,它有許多優點,如“容易使用 ,功能強,動態分配內存,大量進行拷貝時它很能節省內存資源並且執行效率高,與標準C完全兼容,同時支持多字節與寬字節,由於有異常機製所以使用它安全方便” 其實,使用過程中之所以容易出錯,那是因為我們對它了解得還不夠,特別是它的實現機製。因為我們中的大多數人,在工作中並不那麽愛深入地去看關於它的文檔,何況它還是英文的。
由於前幾天我在工作中遇到了一個本不是問題但卻特別棘手、特別難解決而且莫名驚詫的問題。好來最後發現是由於CString引發的。所以沒辦法,我把整個CString的實現全部看了一遍,才慌然大悟,並徹底弄清了問題的原因(這個問題,我已在csdn上開貼)。在此,我想把我的一些關於CString的知識總結一番,以供他(她)人借鑒,也許其中有我理解上的錯誤,望發現者能通知我,不勝感謝。
1. CString實現的機製.
CString是通過“引用”來管理串的,“引用”這個詞我相信大家並不陌生,象Window內核對象、COM對象等都是通過引用來實現的。而CString也是通過這樣的機製來管理分配的內存塊。實際上CString對象隻有一個指針成員變量,所以任何CString實例的長度隻有4字節.
即: int len = sizeof(CString);//len等於4
這個指針指向一個相關的引用內存塊,如圖: CString str("abcd");
‘A’
‘B’
‘C’
‘D’
0
0x04040404 head部,為引用內存塊相關信息
str 0x40404040
正因為如此,一個這樣的內存塊可被多個CString所引用,例如下列代碼:
CString str("abcd");
CString a = str;
CString b(str);
CString c;
c = b;
上麵代碼的結果是:上麵四個對象(str,a,b,c)中的成員變量指針有相同的值,都為0x40404040.而這塊內存塊怎麽知道有多少個CString引用它呢?同樣,它也會記錄一些信息。如被引用數,串長度,分配內存長度。
這塊引用內存塊的結構定義如下:
struct CStringData
{
long nRefs; // 表示有多少個CString 引用它. 4
int nDataLength; // 串實際長度. 4
int nAllocLength; // 總共分配的內存長度(不計這頭部的12字節). 4
};
由於有了這些信息,CString就能正確地分配、管理、釋放引用內存塊。
如果你想在調試程序的時候獲得這些信息。可以在Watch窗口鍵入下列表達式:
(CStringData*)((CStringData*)(this->m_pchData)-1)或
(CStringData*)((CStringData*)(str.m_pchData)-1)//str為指CString實例
正因為采用了這樣的好機製,使得CString在大量拷貝時,不僅效率高,而且分配內存少。