标签:cstring引用计数 引用计数
Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源
问题: CString是否使用了引用计数?
答案是肯定的。平常使用的时候确实没有查觉这方面,包括我们可以把CString强制转为TCAHR*来使用,效果也都正常。
CString强制转为TCAHR*为什么能正常,原因是什么呢?
原因是单纯从数据结构上来看,它仅有一个变量: m_pszData
但它动态申请的内存结构是这样的
[CStringData结构][存储字符串]
而m_pszData指向[存储字符串]
如何来定位CStringData,是这样定位的
CStringData* GetData() const throw() { return( reinterpret_cast< CStringData* >( m_pszData )-1 ); } |
我觉得这个非常巧妙,通过m_pszData往前回退sizeof(CStringData)来查找到CStringData的数据。
至于引用计数、字符段长度、申请长度等相关的数据结构,定义在CStringData结构中
struct CStringData { IAtlStringMgr* pStringMgr; // String manager for this CStringData int nDataLength; // Length of currently used data in XCHARs (not including terminating null) int nAllocLength; // Length of allocated data in XCHARs (not including terminating null) long nRefs; // Reference count: negative == locked // XCHAR data[nAllocLength+1] // A CStringData is always followed in memory by the actual array of character data
void* data() throw() { return (this+1); }
void AddRef() throw() { ATLASSERT(nRefs > 0); _AtlInterlockedIncrement(&nRefs); } bool IsLocked() const throw() { return nRefs < 0; } bool IsShared() const throw() { return( nRefs > 1 ); } void Lock() throw() { ATLASSERT( nRefs <= 1 ); nRefs--; // Locked buffers can‘t be shared, so no interlocked operation necessary if( nRefs == 0 ) { nRefs = -1; } } void Release() throw() { ATLASSERT( nRefs != 0 );
if( _AtlInterlockedDecrement( &nRefs ) <= 0 ) { pStringMgr->Free( this ); } } void Unlock() throw() { ATLASSERT( IsLocked() );
if(IsLocked()) { nRefs++; // Locked buffers can‘t be shared, so no interlocked operation necessary if( nRefs == 0 ) { nRefs = 1; } } } };
__interface IAtlStringMgr { public: // Allocate a new CStringData CStringData* Allocate( int nAllocLength, int nCharSize ) throw(); // Free an existing CStringData void Free( CStringData* pData ) throw(); // Change the size of an existing CStringData CStringData* Reallocate( CStringData* pData, int nAllocLength, int nCharSize ) throw(); // Get the CStringData for a Nil string CStringData* GetNilString() throw(); IAtlStringMgr* Clone() throw(); }; |
注意:
std::auto_ptr是独占的,它没有使用引用计数
它的数据结构中的变量只有一个
_Ty *_Myptr; // the wrapped object pointer
std::shared_ptr采用了引用计数
它的数据结构中的变量有两个
_Ty *_Ptr;
_Ref_count_base *_Rep;
Boost库中的shared_ptr采用了引用计数年
它的数据结构中的变量有两个
T * px; // contained pointer
count_type * pn; // ptr to reference counter
引用计数用于了内存的重用,但对于写操作,肯定是需要重请申请信息的,这种技术称为Copy on Write(写时再Copy)。
Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源
标签:cstring引用计数 引用计数
原文地址:http://blog.csdn.net/chunyexiyu/article/details/45897219