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

拷贝控制示例

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

运行结果:

Message:
        contents1
Appears in 2 Folders
Folder contains 4 messages
Message 1:
        contents6
Message 2:
        contents4
Message 3:
        contents2
Message 4:
        contents1
Message:
        contents1
Appears in 2 Folders
Folder contains 8 messages
Message 1:
        contents6
Message 2:
        contents4
Message 3:
        contents2
Message 4:
        contents1
Message 5:
        contents6
Message 6:
        contents4
Message 7:
        contents2
Message 8:
        contents1
Message:
        contents5
Appears in 1 Folders
Folder contains 4 messages
Message 1:
        contents6
Message 2:
        contents4
Message 3:
        contents2
Message 4:
        contents1
Message:
        contents5
Appears in 0 Folders
Folder contains 4 messages
Message 1:
        contents6
Message 2:
        contents4
Message 3:
        contents2
Message 4:
        contents1
capacity: 0
capacity: 1
capacity: 2
capacity: 3
capacity: 4
capacity: 6
capacity: 0
capacity: 1
capacity: 2
capacity: 3
capacity: 4
capacity: 6
请按任意键继续. . .
原文地址:https://www.cnblogs.com/sunbines/p/9021939.html