C++沉思录笔记 —— 第六章:句柄:第一部分

创建代理将会复制所代理的对象,就像复制代理一样。

目标:如何避免频繁的复制对象。

方法:使用句柄类(handle)。它允许在保持代理的多态行为的同事,还可以避免进行不必要的复制。

Handle类 的对象通常被绑定到它们所控制的类的对象上,这就是它可以避免进行不必要复制的原因。

思考上一句话,你就会发现,Handle类很像指针。

 之所以要使用句柄,原因之一就是为了避免不必要的对象复制,也就是说允许多个句柄绑定到单个对象上。

核心就是一句话:句柄类的实质就是复制指针,而不是去复制对象。复制指针的复制代价是一样的,都是4个字节。

#include <iostream>

using namespace std;

class Point{

public:

    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, yval;

};

class UPoint{

    friend class Handle;

    Point p;

    int u;

    UPoint(): u(1) {}

    UPoint(int x, int y): p(x, y), u(1) {}

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

};

class Handle{

public:

    Handle(): up(new UPoint) {}

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

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

    Handle(const Handle& h): up(h.up) { ++up->u; }

    Handle& operator=(const Handle& h)

    {

        ++h.up->u;

        if(--up->u == 0)

            delete up;

        up = h.up;

        return *this;

    }

    ~Handle()

    { 

        if(--up->u == 0) 

            delete up; 

    }

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

    Handle& x(int x0)

    {

        if(up->u != 1){

            --up->u;

            up = new UPoint(up->p);

        }

        up->p.x(x0);

        return *this;

    }

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

    Handle& y(int y0)

    {

        if(up->u != 1){

            --up->u;

            up = new UPoint(up->p);

        }

        up->p.y(y0);

        return *this;

    }    

private:

    UPoint *up;

};

int main(int argc, char const *argv[])

{

    Handle h(3, 4);

    Handle h2 = h;

    h2.x(5);

    int n = h.x();

    cout << n << endl;

    return 0;

}

posted @ 2019-11-01 16:43    阅读(223)  评论(0)    收藏  举报