13.33
为了实现题目的需求,我们Folder必须指向一个存在的实体,所以不能使用Folder,我们还需要使用remMsg,addMsg来改变其成员变量,所以不能使用const Folder&
13.34
#ifndef MESSAGE_H #define MESSAGE_H #include <string> #include <set> class Folder; class Message { friend class Folder; friend void swap(Message& lhs, Message& rhs); public: explicit Message(const std::string& str = ""):contents(str){} Message(const Message&); Message& operator=(const Message&); ~Message(); void save(Folder&); void remove(Folder&); private: std::string contents; std::set<Folder* > folders; void add_to_Folders(const Message&); void remove_from_Folders(); }; #endif
#include "Message.h" void Message::save(Folder& f){ folders.insert(&f); f.addMsg(this); } void Message::save(Folder& f) { folders.erase(&f); f.remMsg(this); } void Message::add_to_Folders(const Message& m){ for(auto f: m.folders){ f.addMsg(m); } } Message::Message(const Message& m):contents(m.contents),folders(m.folders){ add_to_Folders(*this); } void Message::remove_from_Folders(){ for(auto f: folders){ f->remMsg(this); } } Message::~Message(){ remove_from_Folders(); } Message& Message::operator=(const Message & m){ remove_from_Folders(); contents = m.contents; folders = m.folders; add_to_Folders(m); return m; } void swap(Message& lhs, Message& rhs){ for(auto f:lhs.folders){ f->remMsg(&lhs); } for (auto f : rhs.folders) { f->remMsg(&rhs); } std::swap(lhs.contents, rhs.contents); std::swap(lhs.folders, rhs.folders); for(f:lhs.folders){ f->addMsg(&lhs); }for (f : rhs.folders) { f->addMsg(&rhs); } }
13.35
如若使用合成的拷贝控制成员,新的Message就不会被原来的Folder所获知,在做出修改决定后,该Message将不会被执行到
13.36
#pragma once #include "Message.h" #include <set> class Folder{ public: void remMsg(Message*); void addMsg(const Message*); private: std::set<Message* > messages; };
#include "Folder.h" void Folder::remMsg(Message * m) { this->messages.erase(m); } void Folder::addMsg(const Message * m) { this->messages.insert(m); }
13.37
void insertFolder(Folder *); void eraseFolder(Folder *);
void Message::insertFolder(Folder * f) { this->folders.insert(f); } void Message::eraseFolder(Folder * f) { this->folders.erase(f); }void
13.38
假设我们使用swap来实现赋值运算符,我们会对传入临时变量进行不必要的操作,造成资源浪费,临时变量是会被释放掉的