1. 程式人生 > >【C++ Primer 第十三章】4. 拷貝控制示例

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

XP this 示例 void VM appears 控制 while {}

拷貝控制示例

  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 }

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