C++沉思录句柄类总结1

句柄类作用:

管理对象内存分配和处理对象复制


第一个例子:

class Point
{
public:
	Point():m_x(1), m_y(1){}
	Point( int x, int y ): m_x(x), m_y(y){}
	//复制构造函数和赋值操作符依靠编译器默认定义
	
	int GetX(){ return m_x; }
	int GetY(){ return m_y; }

	Point& SetX( int& x ){ m_x = x; return *this; }
	Point& SetY( int& y ){ m_y = y; return *this; }

private:
	int m_x; 
	int m_y;
};

class Handle;

class UPoint
{
public:
	friend class Handle;
	UPoint(): m_Point(0, 0), m_Count(1){}
	UPoint( int x, int y ): m_Point(x, y), m_Count(1){}
	UPoint(Point& _rP): m_Point(_rP), m_Count(1){}
private:
	Point	m_Point;
	int		m_Count;

};

class Handle
{
public:
	Handle():m_pUPoint(new UPoint()){}
	Handle(int x, int y): m_pUPoint(new UPoint(x, y)){}
	Handle(Point& _rP): m_pUPoint(new UPoint(_rP)){}

	Handle(Handle& _rH): m_pUPoint(_rH.m_pUPoint){ ++(_rH.m_pUPoint->m_Count); }
	Handle& operator= ( Handle& _rH )
	{
		//直接增加右边对象的计数
		//算是优化技巧一种
		++(_rH.m_pUPoint->m_Count);
		//自身对象计数量
		if( --m_pUPoint->m_Count == 0 )
			delete m_pUPoint;
		m_pUPoint = _rH.m_pUPoint;
		return *this;
	}

	~Handle()
	{
		if( --m_pUPoint->m_Count == 0 )
			delete m_pUPoint;
	}

private:
	UPoint* m_pUPoint;
};


这个用了一个class UPoint来管理对象(Point)和计数器(m_Count)。

所以缺点显而易见,不可能每个对象(这里指的是其他需要句柄的类)都需要class UPoint类来管理计数器(m_Count)和对象(Point)。

而且重要的是,如果对象Point万一派生了一个DerviedPoint对象时,class UPoint不是就要重写了?


所以便有了第二个例子


class Point
{
public:
	Point():m_x(0),m_y(0){}
	Point(int x, int y): m_x(x),m_y(y){}
	//复制构造和赋值操作符,直接依靠编译器默认定义。

	int GetX(){ return m_x; }
	int GetY(){ return m_y; }

	Point& SetX(int& x){ m_x = x; return *this; }
	Point& SetY(int& y){ m_y = y; return *this; }

private:
	int m_x;
	int m_y;
};


class Handle
{
public:
	Handle():m_pPoint(new Point(0, 0)), m_pCount(new int(1)){}
	Handle(Point& _rP):m_pPoint(new Point(_rP)), m_pCount(new int(1)){}
	Handle(int x, int y):m_pPoint(new Point(x, y)), m_pCount(new int(1)){}

	Handle(const Handle& _rH): m_pPoint(_rH.m_pPoint), m_pCount(_rH.m_pCount){ ++*_rH.m_pCount; }
	Handle& operator= ( Handle& _rH )
	{
		//直接先增加右边的对象计数器
		//算是技巧的一种吧
		++*_rH.m_pCount;
		//Handle自身创建
		if( --*m_pCount == 0 )
		{
			delete m_pCount;
			delete m_pPoint;
		}
		m_pPoint = _rH.m_pPoint;
		m_pCount = _rH.m_pCount;
		return *this;
	}

	~Handle()
	{ 
		if( --*m_pCount == 0 )
		{
			delete m_pCount;
			delete m_pPoint;
		}
	}
private:
	Point*	m_pPoint;
	int*	m_pCount;
};


好这个例子去掉了管理类class UPoint。

转而将对象(Point)和计数器(m_pCount)放在了Handle中。

也解决了对象(Point)继承问题。

视乎没什么问题了。

但是转头想想。

你妹,我要的是Handle,不要计数器。

我只是需要一个处理对象(Point)内存分配和对象(Point)复制的Handle类,干嘛要去管理繁琐的计数器问题。

为何不让计数器成为单独的类,只让句柄类处理内存和复制。


第三个例子


class Point
{
public:
	Point():m_x(0), m_y(0){}
	Point(int x, int y):m_x(x), m_y(y){}
	
	//复制构造函数和拷贝构造函数实现,依赖编译器

	int GetX() { return m_x; }
	int GetY() { return m_y; }

	Point& SetX( int& x ){ m_x = x; return *this; }
	Point& SetY( int& y ){ m_y = y; return *this; }

private:
	int m_x;
	int m_y;
};


class UseCount
{
public:
	UseCount(): m_pCount(new int(1)){}
	UseCount( const UseCount& _rUC ): m_pCount(_rUC.m_pCount){ ++*_rUC.m_pCount; }
	~UseCount(){ if(--*m_pCount == 0) delete m_pCount; }

	//额外成员函数
	//
	//检测计数器是否只有一的对象
	bool only(){ return *m_pCount == 1;  }
	//取代了operator=操作符
	bool reattach( const UseCount& _rUse )
	{
		++*_rUse.m_pCount;
		if( --*m_pCount == 0 )
		{
			delete m_pCount;
			m_pCount = _rUse.m_pCount;
			return true;
		}
		m_pCount = _rUse.m_pCount;
		return false;
	}


private:
	//只声明不实现
	UseCount& operator= (UseCount& _rUse);
	int *m_pCount;
	bool m_isNull;
};

class Handle
{
public:
	Handle(): m_pPoint(new Point()){}
	Handle(int x, int y): m_pPoint(new Point(x, y)){}
	Handle(Point& _rPoint): m_pPoint(new Point(_rPoint)){}
	Handle(Handle& _rH):m_pPoint(_rH.m_pPoint),m_Use(_rH.m_Use){}

	~Handle(){ if(m_Use.only()) delete m_pPoint; }

	Handle operator= ( Handle& _rH )
	{
		if( m_Use.reattach(_rH.m_Use) )
			delete m_pPoint;
		m_pPoint = m_pPoint;
		return *this;
	}

private:
	UseCount m_Use;
	Point* m_pPoint;
};


这样就将计数器剖离了出来。

而Handle类就成为了只处理内存和复制。

这里略去了关于怎么样用Handle修改Point对象成员变量才算是合理。

以后再说。



参考资料《C++沉思录》第六章与第七章。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值