【C++ Primer 第十三章】4. 拷贝控制示例

拷贝控制示例

  1 #include<iostream>
  2 #include<string>
  3 #include<set>
  4 using namespace std;
  5 
  6 class Folder;
  7 
  8 class Message {
  9     friend void swap(Message&, Message&);
 10     friend class Folder;
 11 public:
 12     explicit Message(const string &str = ""): contents(str) {}
 13     Message(const Message&);             
 14     Message& operator=(const Message&); 
 15     ~Message();  
 16 
 17     Message(Message&&);  
 18     Message& operator=(Message&&); 
 19 
 20     void save(Folder&);
 21     void remove(Folder&);
 22     void debug_print(); 
 23                         
 24 private:
 25     string contents;      
 26     set<Folder*> folders; 
 27 
 28     void add_to_Folders(const Message&);
 29     void move_Folders(Message*);
 30 
 31     void remove_from_Folders();
 32 
 33 
 34     void addFldr(Folder *f) { folders.insert(f); }
 35     void remFldr(Folder *f) { folders.erase(f); }
 36 };
 37 
 38 
 39 class Folder {
 40     friend void swap(Message&, Message&);
 41     friend class Message;
 42 public:
 43     Folder() = default;
 44     Folder(const Folder&);
 45     Folder& operator=(const Folder&);
 46 
 47     Folder(Folder&&);
 48     Folder& operator=(Folder&&);
 49     ~Folder();
 50 
 51     void save(Message&);
 52     void remove(Message&);
 53     void debug_print();
 54 
 55 private:
 56     set<Message*> msgs;
 57 
 58     void add_to_Messages(const Folder&);
 59     void remove_from_Msgs();
 60     void addMsg(Message *m) { msgs.insert(m); }
 61     void remMsg(Message *m) { msgs.erase(m); }
 62     void move_Messages(Folder*);
 63 
 64 };
 65 
 66 /*********************************************************************/
 67 Message::Message(const Message &m) : contents(m.contents), folders(m.folders)
 68 {
 69     add_to_Folders(m);
 70 }
 71 
 72 void Message::add_to_Folders(const Message &m)
 73 {
 74     for (auto f : m.folders)
 75         f->addMsg(this);
 76 }
 77 
 78 Message& Message::operator=(const Message &rhs)
 79 {    
 80     remove_from_Folders();    
 81     contents = rhs.contents;  
 82     folders = rhs.folders;    
 83     add_to_Folders(rhs);
 84     return *this;
 85 }
 86 
 87 void Message::remove_from_Folders()
 88 {
 89     for (auto f : folders) 
 90         f->remMsg(this);   
 91     folders.clear();    
 92 }
 93 
 94 Message::Message(Message &&m) : contents(std::move(m.contents))
 95 {
 96     move_Folders(&m); 
 97 }
 98 
 99 Message& Message::operator=(Message &&rhs)
100 {
101     if (this != &rhs) 
102     {     
103         remove_from_Folders();
104         contents = std::move(rhs.contents); 
105     }
106     return *this;
107 }
108 
109 Message::~Message()
110 {
111     remove_from_Folders();
112 }
113 
114 void Message::save(Folder &f)
115 {
116     folders.insert(&f); 
117     f.addMsg(this);     
118 }
119 
120 void Message::remove(Folder &f)
121 {
122     folders.erase(&f); 
123     f.remMsg(this);   
124 }
125 
126 void Message::debug_print()
127 {
128     cerr << "Message:\n\t" << contents << endl;
129     cerr << "Appears in " << folders.size() << " Folders" << endl;
130 }
131 
132 Folder::Folder(Folder &&f)
133 {
134     move_Messages(&f);  
135 }
136 
137 void Message::move_Folders(Message *m)
138 {
139     folders = std::move(m->folders);
140     for (auto f : folders)
141     {
142         f->remMsg(m);
143         f->addMsg(this);
144     }
145     m->folders.clear();
146 }
147 
148 void swap(Message &lhs, Message &rhs)
149 {
150     using std::swap;
151     for (auto f : lhs.folders)
152         f->remMsg(&lhs);
153     for (auto f : rhs.folders)
154         f->remMsg(&rhs);
155     swap(lhs.folders, rhs.folders);
156     swap(lhs.contents, rhs.contents);
157     for (auto f : lhs.folders)
158         f->addMsg(&lhs);
159     for (auto f : rhs.folders)
160         f->addMsg(&rhs);
161 }
162 
163 /*********************************************************************/
164 
165 Folder::Folder(Folder &&f)
166 {
167     move_Messages(&f);   
168 }
169 
170 Folder& Folder::operator=(Folder &&f)
171 {
172     if (this != &f) {
173         remove_from_Msgs();  
174         move_Messages(&f);   
175     }
176     return *this;
177 }
178 
179 Folder::Folder(const Folder &f) : msgs(f.msgs)
180 {
181     add_to_Messages(f); 
182 }
183 
184 void Folder::add_to_Messages(const Folder &f)
185 {
186     for (auto msg : f.msgs)
187         msg->addFldr(this);  
188 }
189 
190 Folder& Folder::operator=(const Folder &f)
191 {
192     remove_from_Msgs();  
193     msgs = f.msgs;       
194     add_to_Messages(f);  
195     return *this;
196 }
197 
198 void Folder::remove_from_Msgs()
199 {
200     while (!msgs.empty())
201         (*msgs.begin())->remove(*this);
202 }
203 
204 Folder::~Folder()
205 {
206     remove_from_Msgs();
207 }
208 
209 void Folder::save(Message &m)
210 {
211     msgs.insert(&m);
212     m.addFldr(this);
213 }
214 
215 void Folder::remove(Message &m)
216 {
217     msgs.erase(&m);
218     m.remFldr(this);
219 }
220 
221 void Folder::debug_print()
222 {
223     cerr << "Folder contains " << msgs.size() << " messages" << endl;
224     int ctr = 1;
225     for (auto m : msgs) 
226     {
227         cerr << "Message " << ctr++ << ":\n\t" << m->contents << endl;
228     }
229 }
230 
231 
232 int main()
233 {
234     string s1("contents1");
235     string s2("contents2");
236     string s3("contents3");
237     string s4("contents4");
238     string s5("contents5");
239     string s6("contents6");
240     
241     Message m1(s1);
242     Message m2(s2);
243     Message m3(s3);
244     Message m4(s4);
245     Message m5(s5);
246     Message m6(s6);
247 
248     Folder f1;
249     Folder f2;
250 
251     m1.save(f1); m3.save(f1); m5.save(f1);
252     m1.save(f2);
253     m2.save(f2); m4.save(f2); m6.save(f2);
254     
255     m1.debug_print();
256     f2.debug_print();
257 
258     Message c1(m1);
259     Message c2(m2), c4(m4), c6(m6);
260     
261     m1.debug_print();
262     f2.debug_print();
263 
264     m2 = m3;
265     m4 = m5;
266     m6 = m3;
267     m1 = m5;
268 
269     m1.debug_print();
270     f2.debug_print();
271 
272     m2 = m2;
273     m1 = m1;
274 
275     m1.debug_print();
276     f2.debug_print();
277 
278     vector<Message> vm;
279     cout << "capacity: " << vm.capacity() << endl;
280     vm.push_back(m1);
281 
282     cout << "capacity: " << vm.capacity() << endl;
283     vm.push_back(m2);
284 
285     cout << "capacity: " << vm.capacity() << endl;
286     vm.push_back(m3);
287 
288     cout << "capacity: " << vm.capacity() << endl;
289     vm.push_back(m4);
290 
291     cout << "capacity: " << vm.capacity() << endl;
292     vm.push_back(m5);
293 
294     cout << "capacity: " << vm.capacity() << endl;
295     vm.push_back(m6);
296 
297     vector<Folder> vf;
298     cout << "capacity: " << vf.capacity() << endl;
299     vf.push_back(f1);
300 
301     cout << "capacity: " << vf.capacity() << endl;
302     vf.push_back(f2);
303 
304     cout << "capacity: " << vf.capacity() << endl;
305     vf.push_back(Folder(f1));
306 
307     cout << "capacity: " << vf.capacity() << endl;
308     vf.push_back(Folder(f2));
309 
310     cout << "capacity: " << vf.capacity() << endl;
311     vf.push_back(Folder());
312 
313     Folder f3;
314     f3.save(m6);
315     cout << "capacity: " << vf.capacity() << endl;
316     vf.push_back(f3);
317     return 0;
318 }

猜你喜欢

转载自www.cnblogs.com/sunbines/p/9021939.html
今日推荐