///学习了一下《C++沉思录》第六章,手动敲了下代码,加深印象
///本章采用引起计数器的技术避免了对象的复制时进行不必要的开销,同时介绍了指针语义和值语义的区别
#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() 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;
int yval;
};
#endif ///__POINT_H__
#ifndef __UPOINT_H__
#define __UPOINT_H__
#include "Point.h"
#include "Handle.h"
class Handle;
class UPoint
{
friend class Handle; ///该类要用到引用计数器,因为UPoint的成员都是私有的,外部无法访问
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){}
};
#endif ///__UPOINT_H__
#ifndef __HANDLE_H__
#define __HANDLE_H__
#include "UPoint.h"
///Handle类"控制"它所绑定的对象Point,由Handle类来创建和销毁Point
///Handle类对对象的分配和回收拥有完全的控制权,所以没有暴露指针operator->()操作,所以Handle实现了Point提供的操作函数
class Handle
{
public:
Handle();
Handle(int x, int y);
Handle(const Point& p);
Handle(const Handle& h);
Handle& operator=(const Handle& h);
~Handle();
int x() const;
Handle& x(int x0);
int y() const;
Handle& y(int y0);
private:
UPoint* up;
};
#endif ///__HANDLE_H__
#include "Handle.h"
Handle::Handle():up(new UPoint){}
Handle::Handle(int x, int y):up(new UPoint(x, y)){}
Handle::Handle(const Point& p):up(new UPoint(p)){}
Handle::Handle(const Handle& h):up(h.up)
{
++up->u;
}
///赋值操作符,不进行对象的复制,只是将引用计数器+1,这样避免的内存的开销
Handle& Handle::operator=(const Handle& h)
{
++h.up->u;
if (--up->u == 0)
{
delete up;
}
up = h.up;
return *this;
}
Handle::~Handle()
{
if (--up->u == 0)
{
delete up;
}
}
int Handle::x() const
{
return up->p.x();
}
///这里是指针语义
Handle& Handle::x(int x0)
{
up->p.x(x0);
return *this;
}
/*
*这里是值语义,具体区别看《C++沉思录》第六章
Handle& Handle::x(int x0)
{
if (up->u != 1)
{
--up->u;
up = new UPoint(up->p);
}
up->p.x(x0);
return *this;
}
Handle& Handle::y(int y0)
{
if (up->u != 1)
{
--up->u;
up = new UPoint(up->p);
}
up->p.y(y0);
return *this;
}
*/
int Handle::y() const
{
return up->p.y();
}
Handle& Handle::y(int y0)
{
up->p.y(y0);
return *this;
}
#include <iostream>
#include "Point.h"
#include "Handle.h"
using namespace std;
int main()
{
cout << "hello chanhui" << endl;
Point p(1, 2);
Handle h(p);
Handle h1 = h;
cout << h.x() << "\t" << h.y() << endl;
h.x(7);
h.y(8);
cout << h1.x() << "\t" << h1.y() << endl;
return 0;
}