CString 內部使用引用計數的動態字符數組(類似 Copy-On-Write),而非鏈表。
struct CStringData {
long nRefs; // 引用計數
int nDataLength; // 當前字符數
int nAllocLength; // 分配緩衝區長度
// 緊隨其後是字符數組:TCHAR data[nAllocLength + 1];
};
class CString {
CStringData* m_pData; // 指向共享數據塊
// 小字符串優化 (SSO):短字符串直接存儲在對象內部,不分配堆
};
InterlockedIncrement(&nRefs),銷毀時遞減,歸零才 free。SetAt, Append)前檢查 nRefs > 1,是則深拷貝一份新緩衝區。CString 對象內部(佔用 16/32 字節),零堆分配。| 操作 | 動態數組 (CString) | 鏈表 |
|---|---|---|
| 隨機訪問 | O(1) | O(n) |
| 內存局部性 | 極佳 (CPU 緩存友好) | 差 (指針跳轉) |
| 拼接 | O(n) 單次分配 | O(1) 但需遍歷求長 |
| 內存碎片 | 少 | 多 (每節點單獨分配) |
CString s1 = _T("Hello");
CString s2 = s1; // 僅增加引用計數
ASSERT(s1.GetData() == s2.GetData()); // 指向同一塊內存
s2 += _T(" World"); // 觸發 COW,s2 獨享新緩衝區
ASSERT(s1.GetData() != s2.GetData());
理解底層結構有助於避免性能陷阱:如循環中大量 s += ch 應預先 s.GetBufferSetLength(n) 預分配。