![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }