【C++ Primer 第十三章】4. 拷贝控制示例
拷贝控制示例
- #include<iostream>
- #include<string>
- #include<set>
- #include<vector>
- using namespace std;
- class Folder;
- class Message {
- friend void swap(Message&, Message&);
- friend class Folder;
- public:
- explicit Message(const string &str = "") : contents(str) {}
- Message(const Message&);
- Message& operator=(const Message&);
- ~Message();
- Message(Message&&);
- Message& operator=(Message&&);
- void save(Folder&);
- void remove(Folder&);
- void debug_print();
- private:
- string contents;
- set<Folder*> folders;
- void add_to_Folders(const Message&);
- void remove_from_Folders();
- void addFldr(Folder *f) { folders.insert(f); }
- void remFldr(Folder *f) { folders.erase(f); }
- void move_Folders(Message*);
- };
- /*------------------------------------------------------------------------------------------------------*/
- class Folder {
- friend void swap(Message&, Message&);
- friend class Message;
- public:
- Folder() = default;
- Folder(const Folder&);
- Folder& operator=(const Folder&);
- Folder(Folder&&);
- Folder& operator=(Folder&&);
- ~Folder();
- void save(Message&);
- void remove(Message&);
- void debug_print();
- private:
- set<Message*> msgs;
- void add_to_Messages(const Folder&);
- void remove_from_Msgs();
- void addMsg(Message *m) { msgs.insert(m); }
- void remMsg(Message *m) { msgs.erase(m); }
- void move_Messages(Folder*);
- };
- /*---------------------------------------Folder类成员函数--------------------------------------------------*/
- Folder::Folder(const Folder &f) : msgs(f.msgs)
- {
- add_to_Messages(f);
- }
- void Folder::add_to_Messages(const Folder &f)
- {
- for (auto msg : f.msgs)
- msg->addFldr(this);
- }
- Folder& Folder::operator=(const Folder &f)
- {
- remove_from_Msgs();
- msgs = f.msgs;
- add_to_Messages(f);
- return *this;
- }
- void Folder::remove_from_Msgs()
- {
- while (!msgs.empty())
- (*msgs.begin())->remove(*this); // Message类成员函数
- }
- Folder::~Folder()
- {
- remove_from_Msgs();
- }
- Folder::Folder(Folder &&f)
- {
- move_Messages(&f);
- }
- void Folder::move_Messages(Folder *f)
- {
- msgs = std::move(f->msgs);
- f->msgs.clear();
- for (auto m : msgs)
- {
- m->remFldr(f);
- m->addFldr(this);
- }
- }
- Folder& Folder::operator=(Folder &&f)
- {
- if (this != &f)
- {
- remove_from_Msgs();
- move_Messages(&f);
- }
- return *this;
- }
- void Folder::save(Message &m)
- {
- msgs.insert(&m);
- m.addFldr(this);
- }
- void Folder::remove(Message &m)
- {
- msgs.erase(&m);
- m.remFldr(this);
- }
- void Folder::debug_print()
- {
- cerr << "Folder contains " << msgs.size() << " messages" << endl;
- int ctr = ;
- for (auto m : msgs)
- {
- cerr << "Message " << ctr++ << ":\n\t" << m->contents << endl;
- }
- }
- /*---------------------------------------Message类成员函数------------------------------------------------*/
- Message::Message(const Message &m) : contents(m.contents), folders(m.folders)
- {
- add_to_Folders(m);
- }
- void Message::add_to_Folders(const Message &m)
- {
- for (auto f : m.folders)
- f->addMsg(this); // Folder类成员函数
- }
- Message& Message::operator=(const Message &rhs)
- {
- remove_from_Folders();
- contents = rhs.contents;
- folders = rhs.folders;
- add_to_Folders(rhs);
- return *this;
- }
- void Message::remove_from_Folders()
- {
- for (auto f : folders)
- f->remMsg(this);
- folders.clear();
- }
- Message::Message(Message &&m) : contents(std::move(m.contents))
- {
- move_Folders(&m);
- }
- void Message::move_Folders(Message *m)
- {
- folders = std::move(m->folders);
- for (auto f : folders)
- {
- f->remMsg(m);
- f->addMsg(this);
- }
- m->folders.clear();
- }
- Message& Message::operator=(Message &&rhs)
- {
- if (this != &rhs)
- {
- remove_from_Folders();
- contents = std::move(rhs.contents);
- move_Folders(&rhs);
- }
- return *this;
- }
- Message::~Message()
- {
- remove_from_Folders();
- }
- void Message::save(Folder &f)
- {
- folders.insert(&f);
- f.addMsg(this);
- }
- void Message::remove(Folder &f)
- {
- folders.erase(&f);
- f.remMsg(this);
- }
- void Message::debug_print()
- {
- cerr << "Message:\n\t" << contents << endl;
- cerr << "Appears in " << folders.size() << " Folders" << endl;
- }
- void swap(Message &lhs, Message &rhs)
- {
- using std::swap;
- for (auto f : lhs.folders)
- f->remMsg(&lhs);
- for (auto f : rhs.folders)
- f->remMsg(&rhs);
- swap(lhs.folders, rhs.folders);
- swap(lhs.contents, rhs.contents);
- for (auto f : lhs.folders)
- f->addMsg(&lhs);
- for (auto f : rhs.folders)
- f->addMsg(&rhs);
- }
- /*-----------------------------------------------------------------------------------------------------*/
- int main()
- {
- string s1("contents1");
- string s2("contents2");
- string s3("contents3");
- string s4("contents4");
- string s5("contents5");
- string s6("contents6");
- Message m1(s1);
- Message m2(s2);
- Message m3(s3);
- Message m4(s4);
- Message m5(s5);
- Message m6(s6);
- Folder f1;
- Folder f2;
- m1.save(f1); m3.save(f1); m5.save(f1);
- m1.save(f2); m2.save(f2); m4.save(f2);
- m6.save(f2);
- m1.debug_print();
- f2.debug_print();
- Message c1(m1);
- Message c2(m2), c4(m4), c6(m6);
- m1.debug_print();
- f2.debug_print();
- m2 = m3;
- m4 = m5;
- m6 = m3;
- m1 = m5;
- m1.debug_print();
- f2.debug_print();
- m2 = m2;
- m1 = m1;
- m1.debug_print();
- f2.debug_print();
- vector<Message> vm;
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m1);
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m2);
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m3);
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m4);
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m5);
- cout << "capacity: " << vm.capacity() << endl;
- vm.push_back(m6);
- vector<Folder> vf;
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(f1);
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(f2);
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(Folder(f1));
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(Folder(f2));
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(Folder());
- Folder f3;
- f3.save(m6);
- cout << "capacity: " << vf.capacity() << endl;
- vf.push_back(f3);
- return ;
- }
运行结果:
- Message:
- contents1
- Appears in Folders
- Folder contains messages
- Message :
- contents6
- Message :
- contents4
- Message :
- contents2
- Message :
- contents1
- Message:
- contents1
- Appears in Folders
- Folder contains messages
- Message :
- contents6
- Message :
- contents4
- Message :
- contents2
- Message :
- contents1
- Message :
- contents6
- Message :
- contents4
- Message :
- contents2
- Message :
- contents1
- Message:
- contents5
- Appears in Folders
- Folder contains messages
- Message :
- contents6
- Message :
- contents4
- Message :
- contents2
- Message :
- contents1
- Message:
- contents5
- Appears in Folders
- Folder contains messages
- Message :
- contents6
- Message :
- contents4
- Message :
- contents2
- Message :
- contents1
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- capacity:
- 请按任意键继续. . .
【C++ Primer 第十三章】4. 拷贝控制示例的更多相关文章
- C++ Primer : 第十三章 : 拷贝控制之对象移动
右值引用 所谓的右值引用就是必须将引用绑定到右值的引用,我们通过&&来绑定到右值而不是&, 右值引用只能绑定到即将销毁的对象.右值引用也是引用,因此右值引用也只不过是对象的别名 ...
- C++ Primer : 第十三章 : 拷贝控制之拷贝控制和资源管理
定义行为像值的类 行为像值的类,例如标准库容器和std::string这样的类一样,类似这样的类我们可以简单的实现一个这样的类HasPtr. 在实现之前,我们需要: 定义一个拷贝构造函数,完成stri ...
- C++ Primer : 第十三章 : 拷贝控制之拷贝、赋值与销毁
拷贝构造函数 一个构造函数的第一个参数是自身类类型的引用,额外的参数(如果有)都有默认值,那么这个构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是一个引用类型. 合成的拷贝构造函数 在我们没 ...
- C++Primer 第十三章
//1.当定义一个类时,我们显示地或隐式地指出在此类型的对象(注意这里是此类型的对象,而不包括此类型的指针)拷贝,移动,赋值,销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作:拷贝构造函数 ...
- 【C++ Primer | 15】构造函数与拷贝控制
合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...
- C++ Primer : 第十三章 : 拷贝控制示例
/* Message.h */ #ifndef _MESSAGE_H_ #define _MESSAGE_H_ #include <iostream> #include <strin ...
- C++ Primer : 第十三章 : 动态内存管理类
/* StrVec.h */ #ifndef _STRVEC_H_ #define _STRVEC_H_ #include <memory> #include <string> ...
- [C++ Primer] : 第13章: 拷贝控制
拷贝, 赋值与销毁 当定义一个类时, 我们显示地或隐式地指定在此类型的对象拷贝, 移动, 赋值和销毁时做什么. 一个类通过定义5种特殊的成员函数来控制这些操作, 包括: 拷贝构造函数, 拷贝赋值运算符 ...
- 【C++】《C++ Primer 》第十三章
第十三章 拷贝控制 定义一个类时,需要显式或隐式地指定在此类型地对象拷贝.移动.赋值和销毁时做什么. 一个类通过定义五种特殊的成员函数来控制这些操作.即拷贝构造函数(copy constructor) ...
随机推荐
- CentOS6.x下源码安装MySQL5.5
1. 更新yum源:http://www.cnblogs.com/vurtne-lu/p/7405931.html 2. 卸载原有的mysql数据库 [root@zabbix ~]# yum -y r ...
- 数据库索引实现(B+,B-,hash)
★ B-Tree索引:每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历.B-Tree通常意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据. ★ ...
- 如何用matplotlib绘制决策边界
import matplotlib.pyplot as plt import numpy as np import sklearn import sklearn.datasets import skl ...
- jQuery基础 (一)——样式篇(属性与样式)
一.操作特性的DOM方法主要有3个 getAttribute方法 setAttribute方法 removeAttribute方法 注意:而在jQuery中用一个attr()与removeAttr() ...
- 〖C语言学习笔记 〗(二) 数据类型
前言 本文为c语言的学习笔记,很多只是留下来占位的 数据类型 助记:变量就是在内存中挖个坑并给这个坑命名,而数据类型就是挖内存的坑的尺寸 基础类型 整数类型: short int int long i ...
- Nginx 流量带宽等请求状态统计( ngx_req_status)
Nginx 流量带宽等请求状态统计 ( ngx_req_status) 插件下载地址: wget http://nginx.org/download/nginx-1.4.2.tar.gz git c ...
- 挖掘两个Integer对象的swap的内幕
public class SwapTest { public static void main(String[] args) throws Exception { Integer a = 1, b=2 ...
- 【金色】种瓜得瓜,种豆得豆 Gym - 102072H (线段树)
题目链接:https://cn.vjudge.net/problem/Gym-102072H 题目大意:中文题目 具体思路:通过两棵线段树来维护,第一棵线段树来维护当前坐标的点的日增长速度(默认每一年 ...
- 改变checkbox的默认样式
针对于CheckBox默认样式的改变,和选中状态的改变 <label class="checkBox"><input type="checkbox&qu ...
- Python3实现从文件中读取指定行的方法
from:http://www.jb51.net/article/66580.htm 这篇文章主要介绍了Python3实现从文件中读取指定行的方法,涉及Python中linecache模块操作文件的使 ...