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

  • 相关阅读:
    在WCF中使用Flag Enumerations
    WCF开发教程资源收集
    [转]WCF 4 安全性和 WIF 简介
    Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]
    Asp.Net Web API 2第十八课——Working with Entity Relations in OData
    Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
    Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
    Asp.Net Web API 2第十五课——Model Validation(模型验证)
    函数 生成器 生成器表达式
    函数的进阶
  • 原文地址:https://www.cnblogs.com/nzbbody/p/4678658.html
Copyright © 2011-2022 走看看