zoukankan      html  css  js  c++  java
  • 【C++沉思录】句柄2

    1、【C++沉思录】句柄1 存在问题:
    句柄为了绑定到Point的对象上,必须定义一个辅助类UPoint,如果要求句柄绑定到Point的子类上,那就存在问题了。
    2、有没有更简单的办法呢?
    句柄使用Point*直接绑定到Point对象上(包括子类),为了保持多个句柄引用计数的一致性,使用int* 指向引用计数。
    3、代码如下:
    #include "point.h"
    class Handle_2
    {
    public:
    Handle_2():_p(new Point),_u(new int(1)){}

    Handle_2(int x,int y):_p(new Point(x,y)),_u(new int(1)){}

    Handle_2(const Point& rhs):_p(new Point(rhs)),_u(new int(1)){}

    ~Handle_2()
    {
    subRef();
    }

    Handle_2(const Handle_2& rhs)
    {
    addRef(rhs);
    }

    Handle_2& operator=(const Handle_2& rhs)
    {
    if(this != &rhs)
    {
    subRef();
    addRef(rhs);
    }

    return * this;
    }


    int GetX()
    {
    return _p->GetX();
    }

    int GetY()
    {
    return _p->GetY();
    }

    Handle_2& SetX(int x)
    {
    if(*_u == 1) // 当前是唯一的引用
    {
    _p->SetX(x);
    }
    else
    {
    --*_u;
    _p = new Point(x,_p->GetY());
    }
    return *this;
    }

    Handle_2& SetY(int y)
    {
    if(*_u == 1) // 当前是唯一的引用
    {
    _p->SetY(y);
    }
    else
    {
    --*_u;
    _p = new Point(_p->GetX(),y);
    }
    return *this;
    }

    private:
    void addRef(const Handle_2& rhs) // 复制对象指针和引用计数指针,增加引用
    {
    _p = rhs._p;
    _u = rhs._u;
    ++*_u;
    }

    void subRef()// 减少引用,判断是否delete对象和引用计数
    {
    if(--*_u == 0)
    {
    delete _p;
    delete _u;
    }
    }

    private:
    Point* _p;
    int* _u;
    };
    4、这里要手动管理动态内存 int* _u; 同样道理,可以使用栈上对象进行管理,抽象出一个辅助类 UseCount
    class UseCount
    {
    public:
    UseCount():_p(new int(1)){}
    UseCount(const UseCount& rhs)
    {
    addRef(rhs);
    }

    UseCount& operator=(const UseCount& rhs)
    {
    if(this != &rhs)
    {
    subRef();
    addRef(rhs);
    }
    return *this;
    }

    ~UseCount()
    {
    subRef();
    }

    bool IsOnly()
    {
    return (*_p == 1);
    }

    void MakeOnly()
    {
    if(IsOnly()) // 防止已经是only,用户还调用MakeOnly
    {
    return;
    }
    --*_p;
    _p = new int(1);
    }

    private:
    void addRef(const UseCount& rhs)
    {
    _p = rhs._p;
    ++*_p;
    }

    void subRef()
    {
    if(--*_p == 0)
    {
    delete _p;
    }
    }

    private:
    int* _p;
    };

    #include "point.h"
    #include "use_count.h"
    class Handle_2
    {
    public:
    Handle_2():_p(new Point){}

    Handle_2(int x,int y):_p(new Point(x,y)){}

    Handle_2(const Point& rhs):_p(new Point(rhs)){}

    ~Handle_2()
    {
    subRef();
    }

    Handle_2(const Handle_2& rhs)
    {
    addRef(rhs);
    }

    Handle_2& operator=(const Handle_2& rhs)
    {
    if(this != &rhs)
    {
    subRef();
    addRef(rhs);
    }

    return * this;
    }


    int GetX()
    {
    return _p->GetX();
    }

    int GetY()
    {
    return _p->GetY();
    }

    Handle_2& SetX(int x)
    {
    if(_u.IsOnly()) // 当前是唯一的引用
    {
    _p->SetX(x);
    }
    else
    {
    _u.MakeOnly();
    _p = new Point(x,_p->GetY());
    }
    return *this;
    }

    Handle_2& SetY(int y)
    {
    if(_u.IsOnly()) // 当前是唯一的引用
    {
    _p->SetY(y);
    }
    else
    {
    _u.MakeOnly();
    _p = new Point(_p->GetX(),y);
    }
    return *this;
    }

    private:
    void addRef(const Handle_2& rhs)
    {
    _p = rhs._p;
    _u = rhs._u;
    }

    void subRef()
    {
    if(_u.IsOnly())
    {
    delete _p;
    }
    }

    private:
    Point* _p;
    UseCount _u;
    };

  • 相关阅读:
    我终于会手打lct了!
    [模板]Dijkstra-优先队列优化-单源最短路
    99999999海岛帝国后传:算法大会
    正在加载中。。。。。
    【题解】CF1054D Changing Array(异或,贪心)
    【题解】P4550 收集邮票(概率期望,平方期望)
    【题解】CF149D Coloring Brackets(区间 DP,记忆化搜索)
    【笔记】斜率优化 DP
    CSP2021 游记
    【题解】洛谷P1502 窗口的星星
  • 原文地址:https://www.cnblogs.com/nzbbody/p/4678658.html
Copyright © 2011-2022 走看看