有了引用计数器以后为什么还有写时拷贝呢?
因为当我有两个String类s1,s2都是指向同一块空间“helle”,当我想将s1修改成“hello”时,我只想将s1指向的空间修改,而不想将s2修改,显然引用计数器不能解决这个问题,所以就有了更完善的写法--写时拷贝。
写时拷贝
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 5])
{
_str += 4;
GetRefCount(_str) = 1;
strcpy(_str, str);
}
String(String& s)
:_str(s._str)
{
++GetRefCount(_str);
}
String& operator=(const String& s)
{
if (_str != s._str)
{
Release();
_str = s._str;
++GetRefCount(_str);
}
return *this;
}
char& operator[](size_t index)
{
if (GetRefCount(_str) > 1)
{
char* tmp = new char[strlen(_str) + 5];
tmp += 4;
GetRefCount(tmp) = 1;
strcpy(tmp, _str);
--GetRefCount(_str);
_str = tmp;
}
return _str[index];
}
~String()
{
Release();
}
int& GetRefCount(char* str)
{
return *(int*)(str - 4);
}
int _GetRefCount()
{
return GetRefCount(_str);
}
void Release()
{
if (--GetRefCount(_str) == 0)
{
delete[] _str;
}
}
private:
char* _str;
};
void Test1()
{
String s1("s1");
String s2(s1);
s2 = s1;
assert(s1._GetRefCount() == 2);
assert(s2._GetRefCount() == 2);
String s3("s3");
String s4(s3);
s1 = s3;
assert(s1._GetRefCount() == 3);
assert(s2._GetRefCount() == 1);
assert(s3._GetRefCount() == 3);
assert(s4._GetRefCount() == 3);
}
int main()
{
Test1();
system("pause");
return 0;
}
转载于:https://blog.51cto.com/10740329/1745762