【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 }

原文地址:https://www.cnblogs.com/sunbines/p/9021939.html

时间: 2024-08-14 22:21:11

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

《C++primer(第五版)》学习之路-第十三章:拷贝控制

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 13.1 拷贝.赋值与销毁 1.当定义一个类时,我们显式地或隐式地指定在此类型的对象拷贝.移动.赋值和销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符和析构函数. 2.在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照它们在类中出现的顺序进行初始化.在一个析构函数中,首先执行函数体,然后销毁成员.成员按

【足迹C++primer】45、拷贝控制示例

拷贝控制示例 那么接下来尽情欣赏这个案例吧!!! /** * 功能:拷贝控制示例 * 时间:2014年7月14日10:57:39 * 作者:cutter_point */ #include<iostream> #include<set> #include<vector> #include<string> using namespace std; class Folder; /** Message类 */ class Message { friend void

C++Primer 第十三章

//1.当定义一个类时,我们显示地或隐式地指出在此类型的对象(注意这里是此类型的对象,而不包括此类型的指针)拷贝,移动,赋值,销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作:拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符,析构函数. //当定义了五种特殊成员函数的其中一个的时候,一般也需要定义其他几个操作. //拷贝构造函数的第一个参数必须是一个引用类型,若第一个参数不是引用类型则会造成逻辑错误:传值调用会产生一个临时对象,而此对象必须通过类的拷贝构造函数生成,所以会陷

拷贝控制示例

实现二个类,一个是Message,另一个是Folder:类似于消息和消息目录,每个Message对象可以出现在多个Folder中.但是,任意给定的Message的内容只有一个副本.其结构依赖:为了记录Message位于哪些Folder中,每个Message都会保存一个它所在Folder的指针的set,同样的,每个Folder都保存一个它保存一个它包含的Message的指针的set. 首先是Message的头文件: 1#ifndef _MESSAGE_ 2 #define _MESSAGE_ 3

C++primer第十三章 复制控制

每种类型还定义了创建该类型的对象时会发生什么——构造函数定义了该类类型对象的初始化.类型还能控制复制.赋值或撤销该类型的对象时会发生什么——类通过特殊的成员函数:复制构造函数.赋值操作符和析构函数来控制这些行为. 复制构造函数是一种特殊构造函数,具有单个形参,该形参(常用 const 修饰)是对该类类型的引用.当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式使用复制构造函数.当将该类型的对象传递给函数或函数返回该类型的对象时,将隐式使用复制构造函数. 析构函数是构造函数的互补:当对象

第十三章:复制控制

1:复制构造函数,在对象定义初始化时,会出现:此时的=不是赋值效果,而是复制构造函数的效果. 2:复制构造函数,定义在私有中,则禁止了操作,除了友元:若在私有中只是声明不定义,则任何都无法调用构造函数 3:容器是有复制构造函数的. 4:类中指针成员有3种处理方式,一是复制指针的值共享所指对象,这样会带来指针安全问题:二是使用智能指针类可以达到 共享指针所指对象,且没有指针安全问题:三是值类型,通过重新构造新的副本,独立指针所指对象,没有指针安全,但是有复制工程的耗费. 5:复制控制中3中操作,复

《C++ Primer》读书笔记—第十三章 控制拷贝

声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程 第III部分,类设计者的工具 1.类是C++的核心概念.每个类都定义了一个新类型和在此类型对象上可执行的操作. 2.当定义一个类时,我们显式或隐式地指定在此类型的对象的拷贝.移动.赋值和销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数(copy construcor),拷贝赋值运算符(copy-assignment operato

C++11(12):拷贝控制

拷贝构造函数的第一个参数必须是引用类型,此参数几乎总是const的引用.拷贝构造函数在几种情况下会隐式地使用.因此,拷贝构造函数不应该是explicit的 即使我们定义了其他构造函数,在没有拷贝构造函数时,编辑器也会为我们合成的.编辑器从给定对象中依次将每个非static成员拷贝到创建的对象中.每个成员决定了它使用何种方式进行拷贝.类调用拷贝构造函数,数组逐个拷贝,内置类型直接拷贝 string dots(10,'.')  //直接初始化 string noll_book="999999&quo

C++ Primer学习总结 第13章 拷贝控制

第13章 拷贝控制 1.    什么是拷贝构造函数? P440 如果一个类的构造函数的第一个参数是自己类类型的引用, 且所有其他参数都有默认值, 那么这就是一个拷贝构造函数. 2.    拷贝初始化和直接初始化.  P441 如果初始化的时候使用等号"="来初始化一个对象, 那么就是拷贝初始化. 相反, 如果初始化时, 没有用等号"=", 那么就是直接初始化. 如果是拷贝初始化, 那么用的一定是拷贝构造函数(也有可能用移动构造函数). 如果是直接初始化, 那么就用参