C++沉思录读书笔记(6章)-句柄:第一部分

       创建代理会复制所代理的对象,如何避免这些复制呢?

       可以通过句柄(handle)类来实现。句柄类和智能指针有点类似,通过重载句柄类的*和->操作符,可将句柄类改造称为智能指针。

       从效果上来说,handle就是一种只包含单个对象的容器,它通过允许多个handle对象指向同一个对象来避免复制。

       定义句柄类,我们还需要新定义一个类容纳被引用类对象的引用计数和被引用类对象本身

示例代码如下:

#include <iostream>
using namespace std;
class Point
{
private:
	int xval, yval;
public:
	Point() : xval(0), yval(0)
	{
		cout << "Point" << endl;
	}
	Point(int x, int y) : xval(x), yval(y)
	{
		cout << "Point" << endl;
	}
	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;
	}
	~Point()
	{
		cout << "~Point" << endl;
	}
};
class UPoint    //这个类对用户来说是不可见的, 就是一个间接层
{
	friend class Handle;
	Point p;    //Point 对象
	int u;     //计数器

	UPoint():u(1)   //提供所有的point的构造方式
	{
		cout << "UPoint::" << u << endl;
	}
	UPoint(int x, int y):p(x, y), u(1)
	{
		cout << "UPoint::" << u << endl;
	}
	UPoint(const Point &p0) : p(p0), u(1)
	{
		cout << "UPoint::" << u << endl;
	}
	~UPoint()
	{
		cout << "~UPoint::" << u << endl;
	}
};
class Handle
{
private:
	UPoint *up;    //和间接层UPoint打交道了
public:
	Handle();
	Handle(int, int);
	Handle(const Point&);
	Handle(const Handle&);
	Handle& operator=(const Handle&);
	~Handle();
	int x() const;
	Handle& x(int);
	int y() const;
	Handle& y(int);
};

Handle::Handle():up(new UPoint)
{
	cout << "Handle::" <<up->u << endl; 
}

Handle::Handle(int x, int y):up(new UPoint(x, y)) //按创建Point的方式构造handle,handle->UPoint->Point
{
	cout << "Handle::" <<up->u << endl;
}

Handle::Handle(const Point &p):up(new UPoint(p)) //创建Point的副本
{
	cout << "Handle::" <<up->u << endl;
}

Handle::~Handle()
{
	if(--up->u == 0)
	{
		cout << "~Handle::" <<up->u << endl;
		delete up;
	}
	else
	{
		cout << "~Handle::" <<up->u << endl;
	}
}

Handle::Handle(const Handle &h):up(h.up)
{
	++up->u;       //此处复制的是handle,但是底层的point对象并未复制,只是引用计数加1
	cout << "Handle::" <<up->u << endl;
}

Handle& Handle::operator=(const Handle &h)
{
	++h.up->u;       //右边的对象引用计数加1,左边的减1
	if(--up->u == 0)
		delete up;
	up = h.up;
	cout << "Handle::" <<up->u << endl;
	return *this;
}

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

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

Handle& Handle::x(int x0)//假设句柄为指针语义
{
	up->p.x(x0);
	return *this;
}

Handle& Handle::y(int y0)
{
	up->p.y(y0);
	return *this;
}

/*
Handle& Handle::x(int x0)//假设句柄为值语义(写时复制)
{
	if(up->p != 1)
	{
		--up->u;
		up = new UPoint(up->p);
	}
	up->p.x(x0);
	return *this;
}

Handle& Handle::y(int y0)
{
	if(up->p != 1)
	{
		--up->u;
		up = new UPoint(up->p);
	}
	up->p.y(y0);
	return *this;
}
*/

void f(Handle h)   //测试函数,复制handle,但未复制Point
{
	cout << h.x() << h.y() << endl;
}

int main()
{
	Handle h(3,5);
	cout << h.x() << h.y() << endl;
	f(h);

	Point o(10,9);
	Handle a(o);
	Handle b(a);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值