Copy On Write(写时拷贝)使用了“引用计数”,开辟空间时会多开4个字节用于保存引用计数的值。当第一个对象构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它对象需要这块内存时,这个计数为自动累加,当有对象析构时,引用计数会减一,直到最后一个对象析构,此时的引用计数为0,此时,程序才会真正的Free这块从堆上分配的内存。
引用计数就是string类中写时拷贝的原理!
#include<iostream>
#include<Windows.h>
#include<list>
using namespace std;
class String
{
public:
String(const char* str="")
:_str(new char[strlen(str)+5])
{
_str += 4;
strcpy(_str,str);
_GetRefCount(_str) = 1;//初始化引用计数
}
String(String& s)
:_str(s._str)
{
++_GetRefCount(_str);
}
String& operator=(const String&s)
{
if (this != &s)
{
this->~String();
_str = s._str;
++_GetRefCount(_str);
}
return*this;
}
char& operator[](size_t index)
{
if (_GetRefCount(_str) > 1)
{
_Release();
char* tmp = new char[strlen(_str) + 5];
tmp += 4;
strcpy(tmp,_str);
_GetRefCount(_str) = 1;
_str = tmp;
}
return _str[index];
}
~String()
{
_Release();
}
private:
int& _GetRefCount(char* ptr)
{
return *(int*)(ptr - 4);
}
void _Release()
{
if (--_GetRefCount(_str) == 0 )
{
delete[] (_str-4);
cout << "delete" << endl;
}
}
friend ostream& operator<<(ostream& os, const String& s)
{
os << s._str;
return os;
}
private:
char* _str;
};
int main()
{
system("pause");
return 0;
}