13.4 拷贝控制示例
来源:互联网 发布:淘宝网商城女包包 编辑:程序博客网 时间:2024/05/22 05:08
13.33:为什么Message的成员save和remove的参数时一个Folder &?为什么我们不将参数定义为Folder或是const Folder &?
成员内部调用的函数需要改变Folder中的元素,Folder或是const Folder &都无法做到。
13.34:编写本节所描述的Message。
class Folder;class Message {friend void swap(Message &, Message &);string contents;set<Folder*> folders;void add_to_Folders(const Message &);void remove_form_Folders();public:explicit Message(const string &str = "") :contents(str) {}Message(const Message &);~Message();Message & operator = (const Message &);void save(Folder &);void remove(Folder &);};void swap(Message &, Message &);//声明//容器set内部会构造指针的副本Message::Message(const Message &msg) :contents(msg.contents), folders(msg.folders) {add_to_Folders(msg);}Message::~Message() {remove_form_Folders();}Message & Message::operator = (const Message &msg) {remove_form_Folders();contents = msg.contents;folders = msg.folders;//容器set内部会构造指针的副本add_to_Folders(msg);//将本消息添加到指向msg的所有Folder中return *this;}void Message::save(Folder &fd) {folders.insert(&fd);fd.addMsg(this);}void Message::remove(Folder &fd) {folders.erase(&fd);fd.remMsg(this);}void Message::add_to_Folders(const Message &msg) {for (auto f : msg.folders)f->addMsg(this);}void Message::remove_form_Folders() {for (auto f : folders)f->remMsg(this);}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);}
13.35:如果Message使用合成版本的拷贝控制成员,将会发生什么?
当拷贝一个Message时,副本的指针将不会出现在任何一个Folder中(尽管它包含了其所在Folder的指针set)。更严重的,当某Message析构后,其所在Folder中任然保留了该Message的指针,该指针是无效的!
13.36:设计并实现对应的Folder类。此类应该保存一个指向Folder中包含的Message的set。
class Folder {set<Message*> messages;public:void addMsg(Message *const pMsg) { messages.insert(pMsg); }void remMsg(Message *const pMsg) { messages.erase(pMsg); }};
13.37:为Message类添加成员,实现向folders添加或删除一个给定的Folder*。这两个成员类似Folder类的addMsg和remMsg操作。
class Message {//其余成员void addFolder(Folder *const fd) { folders.insert(fd); }void remFolder(Folder *const fd) { folders.erase(fd); }};
13.38:我们并未使用拷贝并交换方式来设计Message的赋值运算符。你认为原因是什么?
如459页所示,使用swap设计的赋值运算符采用的是值传递的方式传递参数,会引起Message中整个set的拷贝;更重要的是,尽管只是值传递,但是swap仍然会更新到运算符右侧的Message的folders,这显然不是我们所希望的。
阅读全文
0 0
- 13.4 拷贝控制示例
- 拷贝控制示例
- 【足迹C++primer】45、拷贝控制示例
- C++ Primer : 第十三章 : 拷贝控制示例
- 拷贝控制
- 拷贝控制
- 拷贝控制
- 拷贝控制
- 拷贝控制
- 示例1.6 文件拷贝
- NIO拷贝文件示例
- C++ 拷贝控制
- (十三)拷贝控制
- 第十三章 拷贝控制
- 13章拷贝控制
- 拷贝控制与资源管理
- 拷贝控制与资源管理
- C++中的拷贝控制
- [译]无损数据压缩算法的历史
- cocoapods安装Ruby环境
- centos 64bit安装arm-none-linux-gnueabi交叉编译工具链
- 说说使用 JavaScript 定时器的正确姿势
- VMware安装ubantu系统时千万不要用easy install模式安装
- 13.4 拷贝控制示例
- SurfaceShader
- HDU 2152(母函数)
- URLDecoder 和 URLEncoder
- 程序在运行程序时报错,问题事件名称:CLR20r3
- maven 3 新特性记录一
- netty客户端引发的线程血案(三)
- 李航:机器学习新动向 从人机交互中学习
- Python--yield关键字的使用