码迷,mamicode.com
首页 > 其他好文 > 详细

CString是否使用了引用计数

时间:2015-05-21 22:36:54      阅读:654      评论:0      收藏:0      [点我收藏+]

标签: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是否使用了引用计数

标签:cstring引用计数   引用计数   

原文地址:http://blog.csdn.net/chunyexiyu/article/details/45897219

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!