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;
    };

  • 相关阅读:
    python,生产环境安装
    neo4j 图数据库
    RNN系列
    机器学习关于AUC的理解整理
    fensorflow 安装报错 DEPENDENCY ERROR
    dubbo Failed to check the status of the service com.user.service.UserService. No provider available for the service
    使用hbase遇到的问题
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk
    gradle 安装
    jenkins 安装遇到的坑
  • 原文地址:https://www.cnblogs.com/nzbbody/p/4678658.html
Copyright © 2011-2022 走看看