模拟string的Copy-On-Write

来源:互联网 发布:银川网络机柜厂家 编辑:程序博客网 时间:2024/04/27 22:48

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;}
1 1
原创粉丝点击