Copy-On-Write的原理:Copy-On-Write一定使用了“引用计数”,是的,必然有一个变量类似于RefCnt。当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的RefCnt为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。
这个RefCnt该存在在哪里呢?如果存放在string类中,那么每个string的实例都有各自的一套,根本不能共有一个RefCnt,如果是声明成全局变量,或是静态成员,那就是所有的string类共享一个了,这也不行,我们需要的是一个最好的方法才行——我们把引用计数单独开辟一块空间出来,然后让相同的维护这一块空间就行了。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
using namespace std;
class String
{
friend ostream& operator <<(ostream &os, String &str);
public:
String(const char * str)
:_str(new char [strlen(str)+1+4])
{
cout << "构造函数" << endl;
_str = _str + 4;
GetCount() = 1;
strcpy(_str, str);
}
String(const String &str)
:_str(str._str)
{
++GetCount();
}
~String()
{
release();
}
String& operator=(String &str)
{
if (this != &str)
{
release();
_str = str._str;
++GetCount();
}
return *this;
}
char &operator[](int index)
{
assert(index >= 0);
assert(index<(int)strlen(_str));
if (GetCount ()> 1)
{
--GetCount();
char *tmp = new char[strlen(_str) + 1 + 4];
strcpy(tmp + 4, _str);
_str = tmp + 4;
GetCount()=1 ;
}
return _str[index];
}
char *c_str()
{
return _str;
}
private:
int& GetCount()
{
return *(int *)(_str - 4);
}
void release()
{
if (--GetCount() == 0)
{
delete[](_str - 4);
_str = NULL;
}
}
private:
char *_str;
};
ostream& operator <<(ostream &os, String &str)
{
os << str._str;
return os;
}
void test1()
{
String str1("12334");
String str2(str1);
String str3("world");
String str4(str3);
str3[3] = 'q';
str2 = str3;
cout << str1 << endl;
cout << str3 << endl;
}
int main()
{
test1();
system("pause");
return 0;
}