reference count (引用计数)的概念其实很简单, 就是每个对象都有一个reference count 用来表明有多少其他的对象目前正保留一个对它的引用(reference). 对象A 想要引用对象B, A 就把B 的 reference count 加 1。 当A 结束了对B 的引用, A 就把 B 的reference count 减 1. 当没有任何对象再引用 B 时, B 的 reference count就减为0, B 就被清除(deallocated), 内存就被释放。清除B的时候, 被B所用的对象的 reference count 也可能减小, 也可能使它们被清除。
MFC 中的 CString VC6.0中是比较简单的,在VS.net平台后就用模板类完全改写了CString. 以下是VC6.0中CString的拷贝构造函数,这里CString使用了引用计数原理,拷贝构造其实是增加引用计数,并不是深拷贝. CString::CString(const CString& stringSrc) { ASSERT(stringSrc.GetData()->nRefs != 0); if (stringSrc.GetData()->nRefs >= 0) { ASSERT(stringSrc.GetData() != _afxDataNil); m_pchData = stringSrc.m_pchData; InterlockedIncrement(&GetData()->nRefs); } else { Init(); *this = stringSrc.m_pchData; } } 我们可以再看看CString重载的赋值运算符 " = " const CString& CString::operator=(const CString& stringSrc) { if (m_pchData != stringSrc.m_pchData) { if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) || stringSrc.GetData()->nRefs < 0) { // actual copy necessary since one of the strings is locked AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); } else { // can just copy references around Release(); ASSERT(stringSrc.GetData() != _afxDataNil); m_pchData = stringSrc.m_pchData; InterlockedIncrement(&GetData()->nRefs); } } return *this; } 这个有条件限制,如果nRefs < 0,将执行深拷贝,否则也是增加引用计数.nRefs < 0,代表缓冲区被锁定. 详细请参考VC6.0安装目录中的源码, CString的源码分布在 strcore.cpp 和 afx.inl中. VS.net平台中,CString 是 ATL::CStringT模板类定义成的多种类型的字符串类,详细情况也可以参考源代码,在afxstr.h中.