拷贝控制示例

  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 = ;
  139. for (auto m : msgs)
  140. {
  141. cerr << "Message " << ctr++ << ":\n\t" << 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:\n\t" << 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 ;
  326. }

运行结果:

  1. Message:
  2. contents1
  3. Appears in Folders
  4. Folder contains messages
  5. Message :
  6. contents6
  7. Message :
  8. contents4
  9. Message :
  10. contents2
  11. Message :
  12. contents1
  13. Message:
  14. contents1
  15. Appears in Folders
  16. Folder contains messages
  17. Message :
  18. contents6
  19. Message :
  20. contents4
  21. Message :
  22. contents2
  23. Message :
  24. contents1
  25. Message :
  26. contents6
  27. Message :
  28. contents4
  29. Message :
  30. contents2
  31. Message :
  32. contents1
  33. Message:
  34. contents5
  35. Appears in Folders
  36. Folder contains messages
  37. Message :
  38. contents6
  39. Message :
  40. contents4
  41. Message :
  42. contents2
  43. Message :
  44. contents1
  45. Message:
  46. contents5
  47. Appears in Folders
  48. Folder contains messages
  49. Message :
  50. contents6
  51. Message :
  52. contents4
  53. Message :
  54. contents2
  55. Message :
  56. contents1
  57. capacity:
  58. capacity:
  59. capacity:
  60. capacity:
  61. capacity:
  62. capacity:
  63. capacity:
  64. capacity:
  65. capacity:
  66. capacity:
  67. capacity:
  68. capacity:
  69. 请按任意键继续. . .

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

  1. C++ Primer : 第十三章 : 拷贝控制之对象移动

    右值引用 所谓的右值引用就是必须将引用绑定到右值的引用,我们通过&&来绑定到右值而不是&, 右值引用只能绑定到即将销毁的对象.右值引用也是引用,因此右值引用也只不过是对象的别名 ...

  2. C++ Primer : 第十三章 : 拷贝控制之拷贝控制和资源管理

    定义行为像值的类 行为像值的类,例如标准库容器和std::string这样的类一样,类似这样的类我们可以简单的实现一个这样的类HasPtr. 在实现之前,我们需要: 定义一个拷贝构造函数,完成stri ...

  3. C++ Primer : 第十三章 : 拷贝控制之拷贝、赋值与销毁

    拷贝构造函数 一个构造函数的第一个参数是自身类类型的引用,额外的参数(如果有)都有默认值,那么这个构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是一个引用类型. 合成的拷贝构造函数   在我们没 ...

  4. C++Primer 第十三章

    //1.当定义一个类时,我们显示地或隐式地指出在此类型的对象(注意这里是此类型的对象,而不包括此类型的指针)拷贝,移动,赋值,销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作:拷贝构造函数 ...

  5. 【C++ Primer | 15】构造函数与拷贝控制

    合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...

  6. C++ Primer : 第十三章 : 拷贝控制示例

    /* Message.h */ #ifndef _MESSAGE_H_ #define _MESSAGE_H_ #include <iostream> #include <strin ...

  7. C++ Primer : 第十三章 : 动态内存管理类

    /* StrVec.h */ #ifndef _STRVEC_H_ #define _STRVEC_H_ #include <memory> #include <string> ...

  8. [C++ Primer] : 第13章: 拷贝控制

    拷贝, 赋值与销毁 当定义一个类时, 我们显示地或隐式地指定在此类型的对象拷贝, 移动, 赋值和销毁时做什么. 一个类通过定义5种特殊的成员函数来控制这些操作, 包括: 拷贝构造函数, 拷贝赋值运算符 ...

  9. 【C++】《C++ Primer 》第十三章

    第十三章 拷贝控制 定义一个类时,需要显式或隐式地指定在此类型地对象拷贝.移动.赋值和销毁时做什么. 一个类通过定义五种特殊的成员函数来控制这些操作.即拷贝构造函数(copy constructor) ...

随机推荐

  1. CentOS6.x下源码安装MySQL5.5

    1. 更新yum源:http://www.cnblogs.com/vurtne-lu/p/7405931.html 2. 卸载原有的mysql数据库 [root@zabbix ~]# yum -y r ...

  2. 数据库索引实现(B+,B-,hash)

    ★ B-Tree索引:每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历.B-Tree通常意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据. ★ ...

  3. 如何用matplotlib绘制决策边界

    import matplotlib.pyplot as plt import numpy as np import sklearn import sklearn.datasets import skl ...

  4. jQuery基础 (一)——样式篇(属性与样式)

    一.操作特性的DOM方法主要有3个 getAttribute方法 setAttribute方法 removeAttribute方法 注意:而在jQuery中用一个attr()与removeAttr() ...

  5. 〖C语言学习笔记 〗(二) 数据类型

    前言 本文为c语言的学习笔记,很多只是留下来占位的 数据类型 助记:变量就是在内存中挖个坑并给这个坑命名,而数据类型就是挖内存的坑的尺寸 基础类型 整数类型: short int int long i ...

  6. Nginx 流量带宽等请求状态统计( ngx_req_status)

    Nginx 流量带宽等请求状态统计 ( ngx_req_status)  插件下载地址: wget http://nginx.org/download/nginx-1.4.2.tar.gz git c ...

  7. 挖掘两个Integer对象的swap的内幕

    public class SwapTest { public static void main(String[] args) throws Exception { Integer a = 1, b=2 ...

  8. 【金色】种瓜得瓜,种豆得豆 Gym - 102072H (线段树)

    题目链接:https://cn.vjudge.net/problem/Gym-102072H 题目大意:中文题目 具体思路:通过两棵线段树来维护,第一棵线段树来维护当前坐标的点的日增长速度(默认每一年 ...

  9. 改变checkbox的默认样式

    针对于CheckBox默认样式的改变,和选中状态的改变 <label class="checkBox"><input type="checkbox&qu ...

  10. Python3实现从文件中读取指定行的方法

    from:http://www.jb51.net/article/66580.htm 这篇文章主要介绍了Python3实现从文件中读取指定行的方法,涉及Python中linecache模块操作文件的使 ...