写时拷贝

来源:互联网 发布:氮泵 副作用 知乎 编辑:程序博客网 时间:2024/06/05 10:32

写时拷贝:通过引用计数实现,相当于对深拷贝的补充。
特点:在分配空间时,多分配(一个 (int) )四个字节,用来记录有多少个指针指向该块空间,当有新的指针指向这块空间,引用计数加1,当要释放时,引用计数减1。(假释放)
当有指针要改变这块空间的内容,再给这个指针分配自己的空间,并且旧空间的引用计数减1,新分配空间的引用计数加1。
这里写图片描述
当s3的内容需要被更改时,将分配新的空间。
这里写图片描述
实现:

//写时拷贝class String{public:    String(const char *str = "")    //初始化        :_str(new char[strlen(str) + 1 + 4])    {        cout << "Sring()" << endl;        _str += 4;    //前4个字节用来存放引用计数         GetCount() = 1;   //引用计数的初始值设置成1         strcpy(_str, str);    }    String(String& s)     //拷贝构造  并没有分配新的空间        :_str(s._str)    {        cout << "Sring(String&)" << endl;        GetCount()++;    }    String& operator=(String& s)  //运算符重载    {        cout << "Sring& operator=" << endl;           if (this != &s)        {            Release();            _str = s._str;            GetCount()++;        }        return *this;    }    ~String()  //析构    {        cout << "~Sring()" << endl;        Release();    }public:    char& operator[](size_t index)   //char & operator[](this,size_t index)    s1[0]='w'的情况     //所以需要给s1新开辟一块空间 旧计数器 - 1,新计数器 = 1    {        if (GetCount() == 1)   //如果计数器为1,则直接返回这个空间        {            return _str[index];             }        GetCount()--;    //计数器不为1  旧计数器 -1        char *tmp = _str;    // char *tmp=this->tmp        _str = new char[strlen(tmp) + 1 + 4];//分配空间        _str += 4;        strcpy(_str, tmp);        GetCount() = 1;  // 新的计数器 = 1        return _str[index];    }private:    int& GetCount()  //  计数    {        return *(int *)(_str - 4);    }    void Release()    //释放    {        if (--GetCount() == 0)  //只有一个空间        {            cout << "释放" << endl;            delete[](_str - 4); //注意释放的时候还有 存放引用计数的4个字节             _str = NULL;        }    }private:    char *_str;};void test(){    String s1 = "abcdef";    String s2 = s1;    String s3 = s1;    String s4 = "qweasd";    s3 = s4;    String s5;    s5 = s1;}int main(){    test();    system("pause");    return 0;}
原创粉丝点击