学习了《C++沉思录》第七章,手动敲下代码,加深点印象
抽象出类UseCount,可以使Handle绑定继承自Point*类型的对象上
#ifndef _POINT_H__
#define _POINT_H__
class Point
{
public:
Point():xval(0), yval(0){}
Point(int x, int y):xval(x), yval(y){}
int x()
{
return xval;
}
int y()
{
return yval;
}
Point& x(int xv)
{
xval = xv;
return *this;
}
Point& y(int yv)
{
yval = yv;
return *this;
}
private:
int xval, yval;
};
#endif ///_POINT_H__
#ifndef _USE_COUNT_H__
#define _USE_COUNT_H__
class UseCount
{
public:
UseCount():p(new int(1)){}
UseCount(const UseCount& u):p(u.p)
{
++*p;
}
~UseCount()
{
if (--*p == 0)
{
delete p;
}
}
bool only()
{
return *p == 1;
}
bool reattach(const UseCount& u)
{
++*u.p;
if (--*p == 0)
{
delete p;
p = u.p;
return true;
}
p = u.p;
return false;
}
bool makeonly()
{
if (*p == 1)
{
return false;
}
--*p;
p = new int(1);
return true;
}
private:
int* p;
};
#endif ///_USE_COUNT_H__
#ifndef _HANDLE_H__
#define _HANDLE_H__
#include "Point.h"
#include "UseCount.h"
/*
* 类Handle绑定2个对象,一个是数据对象Point,另外一个是引用计数器UseCount
* 使用Point*的原因是我们不仅能够将一个Handle绑定到一个Point,还能将其绑定到继承自Point的类的对象
*/
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()
{
if (u.only())
{
delete p;
}
}
Handle& operator=(const Handle& h)
{
if (u.reattach(h.u))
{
delete p;
}
p = h.p;
return *this;
}
int x() const
{
return p->x();
}
int y() const
{
return p->y();
}
Handle& x(int x0)
{
if (u.makeonly())
{
p = new Point(*p);
}
p->x(x0);
return *this;
}
Handle& y(int y0)
{
if (u.makeonly())
{
p = new Point(*p);
}
p->y(y0);
return *this;
}
private:
Point* p;
UseCount u;
};
#endif ///_HANDLE_H__
#include "Point.h"
#include "Handle.h"
#include "UseCount.h"
#include <iostream>
using namespace std;
int main()
{
Handle h(1, 2);
Handle h1 = h;
cout << h1.x() << "\t" << h1.y() << endl;
Point p(7, 8);
Handle h2(p);
h1 = h2;
cout << h1.x() << "\t" << h1.y() << endl;
return 0;
}