• 2.由深拷贝和浅拷贝引发的写时拷贝技术


    一、相关问题

      我们知道,浅拷贝会引发重复释放,导致程序崩溃。而深拷贝虽不会出现上述问题,但是内存空间开销大。所以,有没有一种方法,

      既节省空间,又不会造成程序崩溃呢?

    二、写时拷贝技术

      写时拷贝(Copy-on-write):如果有多个呼叫者同时要求相同资源,他们会共同取得相同的指标指向相同的资源,直到某个呼叫者

                                              尝试修改时,才会复制一个副本给该呼叫者。

    三、例子

      实现string类,在string中添加引用计数器类成员 

    class String;
    //引用计数器类
    class String_rep
    {
        friend class String;
        friend ostream& operator<<(ostream& out, String const& s);
    public:
        String_rep(const char* str = "")
            : m_UseCount(0){
            if(NULL == str){
                m_data = new char[1];
                m_data[0] = '';
            }else{
                m_data = new char[strlen(str) + 1];
                strcpy_s(m_data, strlen(str) + 1, str);
            }
        }
        String_rep(String_rep const& that){
            m_data = new char[strlen(that.m_data) + 1];
            strcpy_s(m_data, strlen(that.m_data) + 1, that.m_data);
        }
        String_rep& operator=(String_rep const& rhs){
            if(this != &rhs){
                delete[] m_data;
                m_data = new char[strlen(rhs.m_data) + 1];
                strcpy_s(m_data, strlen(rhs.m_data) + 1, rhs.m_data);
            }
            return *this;
        }
        ~String_rep(){
            delete[] m_data;
            m_data = NULL;
        }
    public:
        void Increment(){ ++m_UseCount; }
        void Decrement(){
            if(--m_UseCount == 0){
                delete this;
            }
        }
    private:
        char* m_data;
        int m_UseCount;
    };
    class String
    {
        friend ostream& operator<<(ostream& out, String const& s){
            return out << s.m_rep->m_data;
        }
    public:
        String(const char* str = ""){
            m_rep = new String_rep(str);
            m_rep->Increment();
        }
        String(const String& that){
            m_rep = that.m_rep;
            m_rep->Increment();
        }
        String& operator=(String const& rhs){
            if (this != &rhs){
                m_rep->Decrement();
                m_rep = rhs.m_rep;
                m_rep->Increment();
            }
            return *this;
        }
        ~String(){
            m_rep->Decrement();
        }
    public:
        void ToUpper(){
            if (m_rep->m_UseCount > 1){
                String_rep* newRep = new String_rep(m_rep->m_data);
                m_rep->Decrement();
                m_rep = newRep;
                m_rep->Increment();
            }
            char* ch = m_rep->m_data;
            while (*ch != ''){
                *ch -= 32;
                ++ch;
            }
        }
    private:
        String_rep* m_rep;
    };
    int main()
    {
        String s1("hello");
        String s2 = s1;
        String s3("world");
        s3 = s2;
        cout << "s1 = " << s1 << endl;
        cout << "s2 = " << s2 << endl;
        cout << "s3 = " << s3 << endl;
        cout << "----------------------------" << endl;
        s2.ToUpper();
        cout << "s1 = " << s1 << endl;
        cout << "s2 = " << s2 << endl;
        cout << "s3 = " << s3 << endl;
        system("pause");
        return 0;
    }

      运行结果:

      

  • 相关阅读:
    c语言数组指针
    (4)activiti工作流引擎之uel表达式
    (3)activiti流程的挂起和激活
    (2)java程序走一遍工作流activiti
    (1)activiti认识以及数据库和插件配置
    linux 下路由配置
    lvs-dr+keepalived
    LVS-DR 配置测试
    简单认识TCP/IP协议
    mysql 主从同步-读写分离
  • 原文地址:https://www.cnblogs.com/csqtech/p/5761575.html
Copyright © 2020-2023  润新知