C++沉思录笔记 —— 第七章:句柄:第二部分

上一章的句柄类技术有一个缺点:为了把句柄绑到类T的对象上,必须定义一个具有类型T的成员的新类。

解决方法:将引用计数从数据中分离出来。

这个句柄类的核心是:

一、代理我们需要控制的类

二、将引用计数抽象为类,并包含这个类的一个对象

 

#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 UseCount{

public:

    UseCount(): count(new int(1)) {}

    UseCount(const UseCount& u): count(u.count) { ++*count; }

    UseCount& operator=(const UseCount&);

    bool only() { return *count == 1; }

    bool reattch(const UseCount& u){

        ++*u.count;

        if(--*count == 0){

            delete count;

            count = u.count;

            return true;

        }

        count = u.count;

        return false;

    }

    bool makeonly(){

        if(*count == 1)

            return false;

        --*count;

        count = new int(1);

        return true;

    }

    ~UseCount(){

        if(--*count == 0)

            delete count;

    }

private:

    int *count;

};

class Handle{

public:

    Handle(): p(new Point) {}

    Handle(int x, int y): p(new Point(x, y)) {}

    Handle(const Point& p0): p(new Point(p0)) {}

    Handle(const Handle& h): u(h.u), p(h.p) {}

    Handle& operator=(const Handle& h){

        if(u.reattch(h.u))

            delete p;

        p = h.p;

        return *this;

    }

    ~Handle()

    { 

        if(u.only()) 

            delete p; 

    }

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

    Handle& x(int x0){

        if(u.makeonly())

            p = new Point(*p);

        p->x(x0);

        return *this;

    }

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

    Handle& y(int y0){

        if(u.makeonly())

            p = new Point(*p);

        p->y(y0);

        return *this;

    }    

private:

    Point* p;

    UseCount u;

};

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 17:25    阅读(156)  评论(0)    收藏  举报