【C语言】String类的写时拷贝

来源:互联网 发布:bing是什么软件 编辑:程序博客网 时间:2024/06/05 03:21

有了引用计数器以后为什么还有写时拷贝呢?

    因为当我有两个String类s1,s2都是指向同一块空间“helle”,当我想将s1修改成“hello”时,我只想将s1指向的空间修改,而不想将s2修改,显然引用计数器不能解决这个问题,所以就有了更完善的写法--写时拷贝。


  1. 写时拷贝

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;}


0 0