分类: C/C++
2015-03-03 10:34:56
1
2
3
4
5
6
7
8
9
10
11
|
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;
}
|
1
2
3
4
5
6
7
8
9
10
11
|
class handle {
public:
Handle();
Handle(int, int);
Handle(const Point &);
Handle(const Handle &);
Handle &operator=(const Handle &);
~Handle();
private:
Point *p;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
class handle {
public:
Handle();
Handle(int, int);
Handle(const Point &);
Handle(const Handle &);
Handle &operator=(const Handle &);
Handle &x(int);
~Handle();
private:
Point *p;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class handle {
public:
Handle();
Handle(int, int);
Handle(const Point &);
Handle(const Handle &);
Handle &operator=(const Handle &);
Handle &x(int);
~Handle();
private:
Point *p;
int *u;
}
|
1
2
3
4
5
6
7
8
9
|
// 首先定义一个新的句柄,并绑定到一个新的Point对象,x为3,y为4
Handle h(3, 4);
// 然后通过复制构造函数,使h2也绑定到这个对象
Handle h2 = h;
// 这句话值得玩味,我们的目的到底是设置绑定的那个Point对象的x值为5
// 还是说我们只是希望这个句柄的值为5
h2.x(5);
// 这里取得的值,你究竟希望它是3,还是5呢?
int n = h.(x);
|
1
|
h1 = h;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Handle::Handle() : u(new int(1)), p(new Point) { }
Handle::Handle(int x, int y) : u(new int(1)), p(new Point(x, y)) { }
Handle::Handle(const Point &p0) : u(new int(1)), p(new Point(p0)) { }
Handle::Handle(const Handle &h) : u(h.u), p(h.p) { ++*u; }
Handle & Handle::operator=(const handle &h)
{
// 增加=号右侧句柄的引用计数,注意,必须先增加=号右侧的引用计数,
// 否则当把句柄赋值给自己时Point就被删除了
++*h.u;
// 减少=号左侧句柄的引用计数,如果为0了,则删除绑定的对象副本
if (--*u == 0)
{
delete u;
delete p;
}
u = h.u;
p = h.p;
return *this;
}
Handle::~Handle()
{
if (--*u == 0)
{
delete u;
delete p;
}
}
|
1
2
3
4
5
|
Handle &Handle::x(int x0)
{
p->x(x0);
return *this;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Handle &Handle::x(int x0)
{
/*
这里比较的目的是如果引用计数大于1,代表有多个句柄指向该对象,
所以我们需要减少引用计数,如果引用计数为1,
代表只有这一个句柄指向这个对象,
既然,我要修改这个对象的值,那么直接改原对象就可以了。
*/
if (*u != 1)
{
--*u;
p = new Point(*p);
}
p->x(x0);
return *this;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
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; } // 返回该引用计数是否为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:
UseCount &operator=(const UseCount &);
private:
int *p;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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() { if (u.only()) delete p; }
Handle &operator=(const handle &h) {
if (u.reattach(h.u)) delete p;
p = h.p;
return *this;
}
Handle &x(int x0) {
if (u.makeonly()) p = new Point(*p);
p->x(x0);
return *this;
}
private:
Point *p;
UseCount u;
}
|