zoukankan      html  css  js  c++  java
  • 写时拷贝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] = '';
            }
            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 != '')
        {
            *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;
    }
     
     
     
     
     
     
  • 相关阅读:
    [重回VB6]简单的QQWeb网游辅助工具开发之旅1、序言,另类的QQ登陆方法
    QQ和360大战我的观点
    不用IE Test ,快速对IE兼容性进行测试
    第八届软件设计大赛完全作品赛前评析与剧透
    屌丝如何分发大文件(大于1G)
    NetDog 酷炫版 0.1测试版发布
    Jquery制作的页码插件
    使用Html5+CSS3摆脱JS做带提示文字的输入框
    在nhibernate中,Load相同ID的实体对象的时候出错的问题!
    fieldset,legend
  • 原文地址:https://www.cnblogs.com/enumhack/p/7473082.html
Copyright © 2011-2022 走看看