C++沉思录-句柄类1

看了下《C++沉思录》第六章的内容介绍的是句柄第一部分,采用引用计数器的方式减少内存的拷贝

动手敲了下代码加深点印象,加了点注释

class Point
{
public:
    ///无参数的构造函数的作用:对于要创建一个Point的数组来说,
    ///我们可能只采用一个带缺省参数的构造函数
    Point():xval(0), yval(0){}
    Point(int x, int y): xval(x), yval(y){}

    int x() const {return xval;}
    int y() const {return yval;}

    Point& x(int xv)
    {
        xval = xv;
        return *this;
    }

Point& y(int yv)
    {
        yval = yv;
        return *this;
    }
private:
    int xval;
    int yval;
};

Point类代表的是坐标系上的1个点,Point类有2个成员变量xval和yval,有2个构造函数,有获取xval,yval这两个值得函数x(),y(),有设置xval,yval这两个值得函数x(),y()

-------------------句柄类------------------------------------------
class Handle
{
public:
    Handle();
    ~Handle();
    Handle(int x, int y);
    Handle(const Point &p0);

    Handle(const Handle& h0);
    Handle& operator=(const Handle& h0);

    int x() const;
    int y() const;
    Handle& x(int xval);
    Handle& y(int yval);
private:
    UPoint *up;
};

Handle::Handle():up(new UPoint()){}

Handle::~Handle()
{
    ///引用计数器没有减到0,不释放内存
    if (--up->u)
    {
        delete up;
        up = NULL;
    }
}

Handle::Handle(int x, int y):up(new UPoint(x, y)){}

Handle::Handle(const Point &p0):up(new UPoint(p0)){}

///拷贝构造函数,引用计数器++
Handle::Handle(const Handle& h):up(h.up)
{
    ++up->u;
}

///等号操作符,先递增右侧的引用计数器,再递减左侧引用计数器
///这一操作即使左右两个句柄引用同一个UPoint对象也能正常工作
Handle& Handle::operator=(const Handle& h)
{
    ++h.up->u;
    if (--up->u == 0)
    {
        delete up;
    }

    up = h.up;

    return *this;
}

int Handle::x() const
{
    return up->p.x();
}

int Handle::y() const
{
    return up->p.y();
}

Handle& Handle::x(int xval)
{
    up->p.x(xval);

    return *this;
}

///指针语义
Handle& Handle::y(int yval)
{
    up->p.y(yval);

    return *this;
}


///值语义
/*
Handle h(3, 4);
Handle h2 = h;
h2.x(5);
int n = h.x();      ///是3还是5
Handle& Handle::x(int xval)
{
    if (up->u != 1)
    {
        --up->u;
        up = new UPoint(up->p)
    }

    up->p.x(xval);

    return *this;
}
*/

handle应该控制它所绑定的对象,就是由handle创建和销毁对象,从效果上来讲handle就是一种只包含单个对象的容器,如果不想暴露Point的具体操作,就必须明确的选择让handle类支持那些Point操作

----------------UPoint---------------------------
///为什么需要UPoint这个类?该类用来容纳引用计数器和一个Point对象,
///这个类存粹是为了实现而设计的

class UPoint
{
    ///这里Hnandle需要访问UPoint类的成员变量,所以声明称UPoint的友元,位置不要搞反了
    friend class Handle;

    UPoint():u(1){}
    UPoint(int x, int y):p(x, y), u(1){}
    UPoint(const Point& p0):p(p0), u(1){}

    Point p;
    int u;
};

/*
 * 句柄类可以避免内存的重复拷贝
 */

int main()
{
    Point p(7, 8);
    Handle h(p);

    Handle h2 = h;

    cout << h2.x() << " " << h2.y() << endl;

    cout << "**************TvT*****************" << endl;

    return 0;
}
 

这个句柄类有一个缺点就是引用计数器和对象本身是存放在UPoint中的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值