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

    因为当我有两个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;
}