拷贝控制示例
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 请按任意键继续. . .