写时拷贝COW(copy-on-write)

    写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真的释放掉这块空间。当有的指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时引用计数的变化,旧的空间的引用计数减一,新分配的空间引用计数加一)。
#include<iostream>
#include<new.h>
#include<string>
using namespace std;

//1解决内存泄漏
//2编写赋值语句
//3写时拷贝
class String;
ostream& operator<<(ostream &out, const String &s);

/////////////////////////////////////////////////////////////////////
class String_rep
{
    friend class String;
    friend ostream& operator<<(ostream &out, const String &s);

private:
    String_rep(const char *str = "") : use_count_(0)
    {
        if (str == NULL)
        {
            data = new char[1];
            data[0] = '\0';
        }
        else
        {
            data = new char[strlen(str) + 1];
            strcpy(data, str);
        }
    }
    String_rep(const String_rep &rep)
    {
        this->data = rep.data;
    }
    String_rep& operator=(const String_rep &rep)
    {
        this->data = rep.data;
    }
    ~String_rep()
    {
        if (data != NULL)
        {
            delete[]data;
            data = NULL;
        }
    }
public:
    void increment()
    {
        ++use_count_;
    }

    void decrement()
    {
        //引用计数为0,释放共享内存
        if (--use_count_ == 0)
            delete this;
    }

private:
    char *data;
    int use_count_;
};

//////////////////////////////////////////////////////
class String
{
    friend ostream& operator<<(ostream& out, const String &s);

public:
    String(const char *str = "") :rep(new String_rep(str))
    {
        rep->increment();
    }
    String(const String &s)
    {
        rep = s.rep;
        rep->increment();
    }
    String& operator=(const String &s)
    {
        if (&s != this)
        {
            this->rep->decrement();      //原有共享内存中的引用计数减一
            this->rep = s.rep;
            this->rep->increment();      //现有引用计数加一
        }
        return *this;
    }
    ~String()
    {
        //String析构一次,引用计数减一
        rep->decrement();
    }

public:
    void to_upper();
    String& operator+=(const String &str);

private:
    String_rep *rep;
};

/////////////////////////////////////////////////////////////////////////
ostream& operator<<(ostream &out, const String &s)
{
    out << s.rep->data;
    return out;
}

//创建新的共享内存原来共享内存中值一样,然后再修改
void String::to_upper()
{
    String *newStr = new String(this->rep->data);
    this->rep->decrement();
    this->rep = newStr->rep;
    this->rep->increment();

    char *str = this->rep->data;
    while (*str != '\0')
    {
        *str -= 32;
        ++str;
    }
    delete newStr;
}

String& String::operator+=(const String &str)
{
    char *ch = new char[strlen(str.rep->data) + strlen(this->rep->data) + 1];
    strcpy(ch,this->rep->data);
    strcat(ch, str.rep->data);

    this->rep->decrement();
    String_rep *s = new String_rep(ch);
    this->rep = s;
    this->rep->increment();

    return *this;
}

int main()
{
    String s("abc");
    String s1;
    s1 = s; //
    String s2("xyz");
    String s3(s);
    s2.to_upper();
    
    s3 += s2;
    cout << s2 << endl;
    cout << s3 << endl;

    return 0;
}

 

 
 

 

posted @ 2017-09-04 12:48  actually96  阅读(404)  评论(0编辑  收藏  举报