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 转载请标明来源

时间: 2024-08-02 08:19:38

CString是否使用了引用计数的相关文章

C++ BitArray 引用计数实现

1 #ifndef __BITARRAY__ 2 #define __BITARRAY__ 1 3 4 #include <cstdio> 5 #include <cstring> 6 7 #if __cplusplus >= 201103L 8 #include <cstdint> 9 #else 10 #include <stdint.h> 11 #endif 12 13 #if __cplusplus < 201103L 14 #defin

实现类似shared_ptr的引用计数

13.27 定义使用引用计数版本的HasPtr #include<iostream> #include<string> #include<new> using namespace std; class HasPtr { public: HasPtr(const string &s=string()):ps(new string(s)),i(0),use(new size_t(1)) {cout<<"constructer"<

深拷贝&amp;浅拷贝&amp;引用计数&amp;写时拷贝

(1).浅拷贝: class String { public: String(const char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str,str); } ~String() { if(NULL!=_str) { delete[] _str; _str=NULL; } } private: char* _str; }; int main() { String s1("hello"); String

手工引用计数中规则

使用设值方法为属性赋值时 assign.retain.copy三个特性的实现 self.property = newValue; assign的特性会是这样: property = newValue; retain特性会是这样 if (property!=0) { [property release]; property = [newValue retain]; } copy的特性会是这样 if (property!=0) { [property release]; property = [ne

Objective-C中的引用计数

导言 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器.如果想使某个对象继续存活,那就递增其引用计数:用完了之后,就递减其计数.计数为0,就表示没人关注此对象了,于是,就可以把它销毁. 从Mac OS X 10.8开始,“垃圾收集器”(garbage collector)已经正式废弃了,以Objective-C代码编写Mac OS X程序时不应再使用它,而iOS则从未支持过垃圾收集.因此,掌握引用计数机制对于学好Objective-C来说十分重要.

引用计数

在引用计数中,每一个对象负责维护对象所有引用的计数值.当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减.当引用计数到零时,该对象就将释放占有的资源.中文名引用计数原 因程序调试原 理每一个对象负责维护对象所有引用的计数值类 型最直观的垃圾收集策略目录1简介2引用计数的使用? 原因? 规则? 接口? 调试? 优化? 规则1简介编辑 最直观的垃圾收集策略是引用计数.引用计数很简单,但是需要编译器的重要配合,并且增加了赋值函数 (mutator) 的开销(这个术语是针对用户

基于引用计数的智能指针

编程语言中实现自动垃圾回收机制方式有好几种,常见的有标记清除,引用计数,分代回收等. C++需要手动管理垃圾,可以自己实现一个智能指针.最简单的是引用计数的思路 template <class T> class SmartPointer { T* obj; unsigned int* count; SmartPointer(T* ptr) { obj = ptr; count = new int; *count = 1; } SmartPointer(SmartPointer &p)

ARC自动引用计数

启动自动引用计数选项. 选择项目的属性文件 --> 搜索 automatic Reference --> Objective-C Automatic Reference Counting --> Yes ARC 和手动管理内存的区别. ARC 并不是GC在运行中判断引用计数是否为0,从而清除内存.而是在代码编译之前通过静态分析工具Analyze自动生成内存管理代码. 开启ARC后,不能再使用retain等系列手动内存管的方法,可以重写dealloc方法但不能再方法中[super deal

netty的引用计数

netty的引用计数文档看http://netty.io/wiki/reference-counted-objects.html 为什么会引用引用计数呢,Java中不是有gc线程帮我们回收对象吗?我个人理解如下 1:netty为了实现zero copy使用了Direct Buffer,该buffer从Native Memory分配出来,分配和回收效率要远低于在Java Heap上的对象,所以一般full gc来控制的,直接内存会自己检测情况而调用system.gc(),通过使用引用计数可以自己来