Operator Overloading part 3(Chapter 12 of Thinking in C++)
reference counting 1 #include <string>
2 #include <iostream>
3 using namespace std;
4
5 class Dog
6 {
7 string nm;
8 int refcount;
9 Dog(const string& name) : nm(name), refcount(1)
10 {
11 cout << "Creating Dog:" << *this << endl;
12 }
13
14 Dog& operator=(const Dog& rv);
15 public:
16 static Dog* make(const string& name)
17 {
18 return new Dog(name);
19 }
20
21 Dog(const Dog& d) : nm(d.nm + " copy"), refcount(1)
22 {
23 cout << "Dog copy-constructor: " << *this << endl;
24 }
25
26 ~Dog()
27 {
28 cout << "Deleting Dog: " << *this << endl;
29 }
30
31 void attach()
32 {
33 ++refcount;
34 cout << "Attached Dog:" << *this << endl;
35 }
36
37 void detach()
38 {
39 cout << "Detaching Dog: " << *this << endl;
40 if(--refcount == 0)
41 {
42 delete this;
43 }
44 }
45
46 Dog* unalias()
47 {
48 cout << "Unaliasing Dog: " << *this << endl;
49 if(refcount == 1)
50 {
51 return this;
52 }
53 --refcount;
54 return new Dog(*this);
55 }
56
57 void rename(const string& newName)
58 {
59 nm = newName;
60 cout << "Dog renamed to " << *this << endl;
61 }
62
63 friend ostream& operator<<(ostream& os, const Dog& d)
64 {
65 return os << "[" << d.nm << "], rc = " << d.refcount;
66 }
67 };
68
69
70 class DogHouse
71 {
72 Dog* p;
73 string houseName;
74 public:
75 DogHouse(Dog* dog, const string& house) : p(dog), houseName(house)
76 {
77 cout << "Creating DogHouse: " << *this << endl;
78 }
79
80 DogHouse(const DogHouse& dh) : p(dh.p), houseName("copy-constructed " + dh.houseName)
81 {
82 p->attach();
83 cout << "DogHouse copy-constructed: " << *this << endl;
84 }
85
86 DogHouse& operator=(const DogHouse& dh)
87 {
88 if(&dh != this)
89 {
90 houseName = dh.houseName + " assigned";
91 p->detach();
92 p = dh.p;
93 p->attach();
94 }
95
96 cout << "DogHouse operator= : " << *this << endl;
97 return *this;
98 }
99
100 ~DogHouse()
101 {
102 cout << "DogHouse destructor: " << *this << endl;
103 p->detach();
104 }
105
106 void renameHouse(const string& newName)
107 {
108 houseName = newName;
109 }
110
111 void unalias()
112 {
113 p = p->unalias();
114 }
115
116 void renameDog(const string& newName)
117 {
118 unalias();
119 p->rename(newName);
120 }
121
122 Dog* getDog()
123 {
124 unalias();
125 return p;
126 }
127
128 friend ostream& operator<<(ostream& os, const DogHouse& dh)
129 {
130 return os << "[" << dh.houseName << "] contains " << *dh.p;
131 }
132
133 };
134
135 int main()
136 {
137 DogHouse fidos(Dog::make("Fido"), "FidoHouse"), spots(Dog::make("Spot"), "SpotHouse");
138 cout << "Entering copy-construction" << endl;
139 DogHouse bobs(fidos);
140 cout << "After copy-constructing bobs" << endl;
141 cout << "fidos:" << fidos << endl;
142 cout << "spots:" << spots << endl;
143 cout << "bobs:" << bobs << endl;
144 cout << "Entering spots = fidos" << endl;
145 spots = fidos;
146 cout << "After spots = fidos" << endl;
147 cout << "spots:" << spots << endl;
148 cout << "Entering self-assignment" << endl;
149 bobs = bobs;
150 cout << "After self-assignment" << endl;
151 cout << "bobs:" << bobs << endl;
152 // Comment out the following lines:
153 cout << "Entering rename(\"Bob\")" << endl;
154 bobs.getDog()->rename("Bob");
155 cout << "After rename(\"Bob\")" << endl;
156 }
2 #include <iostream>
3 using namespace std;
4
5 class Dog
6 {
7 string nm;
8 int refcount;
9 Dog(const string& name) : nm(name), refcount(1)
10 {
11 cout << "Creating Dog:" << *this << endl;
12 }
13
14 Dog& operator=(const Dog& rv);
15 public:
16 static Dog* make(const string& name)
17 {
18 return new Dog(name);
19 }
20
21 Dog(const Dog& d) : nm(d.nm + " copy"), refcount(1)
22 {
23 cout << "Dog copy-constructor: " << *this << endl;
24 }
25
26 ~Dog()
27 {
28 cout << "Deleting Dog: " << *this << endl;
29 }
30
31 void attach()
32 {
33 ++refcount;
34 cout << "Attached Dog:" << *this << endl;
35 }
36
37 void detach()
38 {
39 cout << "Detaching Dog: " << *this << endl;
40 if(--refcount == 0)
41 {
42 delete this;
43 }
44 }
45
46 Dog* unalias()
47 {
48 cout << "Unaliasing Dog: " << *this << endl;
49 if(refcount == 1)
50 {
51 return this;
52 }
53 --refcount;
54 return new Dog(*this);
55 }
56
57 void rename(const string& newName)
58 {
59 nm = newName;
60 cout << "Dog renamed to " << *this << endl;
61 }
62
63 friend ostream& operator<<(ostream& os, const Dog& d)
64 {
65 return os << "[" << d.nm << "], rc = " << d.refcount;
66 }
67 };
68
69
70 class DogHouse
71 {
72 Dog* p;
73 string houseName;
74 public:
75 DogHouse(Dog* dog, const string& house) : p(dog), houseName(house)
76 {
77 cout << "Creating DogHouse: " << *this << endl;
78 }
79
80 DogHouse(const DogHouse& dh) : p(dh.p), houseName("copy-constructed " + dh.houseName)
81 {
82 p->attach();
83 cout << "DogHouse copy-constructed: " << *this << endl;
84 }
85
86 DogHouse& operator=(const DogHouse& dh)
87 {
88 if(&dh != this)
89 {
90 houseName = dh.houseName + " assigned";
91 p->detach();
92 p = dh.p;
93 p->attach();
94 }
95
96 cout << "DogHouse operator= : " << *this << endl;
97 return *this;
98 }
99
100 ~DogHouse()
101 {
102 cout << "DogHouse destructor: " << *this << endl;
103 p->detach();
104 }
105
106 void renameHouse(const string& newName)
107 {
108 houseName = newName;
109 }
110
111 void unalias()
112 {
113 p = p->unalias();
114 }
115
116 void renameDog(const string& newName)
117 {
118 unalias();
119 p->rename(newName);
120 }
121
122 Dog* getDog()
123 {
124 unalias();
125 return p;
126 }
127
128 friend ostream& operator<<(ostream& os, const DogHouse& dh)
129 {
130 return os << "[" << dh.houseName << "] contains " << *dh.p;
131 }
132
133 };
134
135 int main()
136 {
137 DogHouse fidos(Dog::make("Fido"), "FidoHouse"), spots(Dog::make("Spot"), "SpotHouse");
138 cout << "Entering copy-construction" << endl;
139 DogHouse bobs(fidos);
140 cout << "After copy-constructing bobs" << endl;
141 cout << "fidos:" << fidos << endl;
142 cout << "spots:" << spots << endl;
143 cout << "bobs:" << bobs << endl;
144 cout << "Entering spots = fidos" << endl;
145 spots = fidos;
146 cout << "After spots = fidos" << endl;
147 cout << "spots:" << spots << endl;
148 cout << "Entering self-assignment" << endl;
149 bobs = bobs;
150 cout << "After self-assignment" << endl;
151 cout << "bobs:" << bobs << endl;
152 // Comment out the following lines:
153 cout << "Entering rename(\"Bob\")" << endl;
154 bobs.getDog()->rename("Bob");
155 cout << "After rename(\"Bob\")" << endl;
156 }

浙公网安备 33010602011771号