標籤:
#pragma once#include<string>#include<set>using namespace std;class Message{ friend class Folder; friend void swap(Message &lhs, Message &rhs);public: explicit Message(const string &str=""):contents(str){} Message(const Message&); Message& operator=(const Message);//採用非參考型別,實現自賦值情況出現時,也能成功,但多了一次拷貝構造 ~Message(); void save(Folder &); void remove(Folder &);private: string contents; set<Folder*> folders; void add_to_Folders(const Message&); void remove_from_Folders();};class Folder{public: Folder(const Folder&);//拷貝建構函式 Folder& operator=(const Folder);//拷貝賦值運算子,採用非參考型別,實現出現自賦值情況時,也能成功,但多了一次拷貝構造 ~Folder(); //解構函式 void addMsg(Message *); //添加message void remMsg(Message *); //去除messageprivate: set<Message*> Mes; void addAllMsg(); //拷貝建構函式和拷貝賦值預算符的輔助函數 void removeAllMsg(); //拷貝賦值運算子和解構函式的輔助函數};void Folder::addMsg(Message *m){ if(Mes.find(m)==Mes.end())//防止在調用m->save(*this)時的從複插入(雖然重複插入對於set來說沒什麼關係) Mes.insert(m); if (m->folders.find(this) == m->folders.end())//給遞迴調用一個結束條件,防止無限調用 m->save(*this);}void Folder::remMsg(Message *m){ if (Mes.find(m) != Mes.end())//防止在調用m->remove(*this)時的從複刪除(雖然重複刪除對於set來說沒什麼關係) Mes.erase(m); if (m->folders.find(this) != m->folders.end())//給遞迴調用一個結束條件,防止無限調用 m->remove(*this);}void Folder::addAllMsg() //拷貝建構函式和拷貝賦值預算符的輔助函數{ for (auto &m : Mes) //對Mes集合中的每一個指標對象都調用save()函數 m->save(*this);}Folder::Folder(const Folder &f){ Mes = f.Mes; //將f中資料成員拷貝過來 addAllMsg(); //調用addALLMsg將這個Folder添加到所有對應的message中去}void Folder::removeAllMsg() //拷貝賦值運算子和解構函式的輔助函數{ for (auto &m : Mes) //對Mes集合中的每一個指標對象都調用remover()函數 m->remove(*this);}Folder& Folder::operator=(const Folder f)//採用非參考型別是為了保護出現自賦值的情況時,也能正常運行{ removeAllMsg(); //將資料成員中所包含的所有message都調用remove()函數,實現刪除這個檔案夾的作用 Mes = f.Mes; //將新的資料成員拷貝過來 addAllMsg(); //將資料成員中所包含的所有message都調用remover()函數,完成為這個檔案夾賦值右側檔案夾的步驟 return *this;}Folder::~Folder(){ removeAllMsg(); //將資料成員中所包含的所有message都調用remove()函數,實現刪除這個檔案夾的作用}void Message::save(Folder &f){ folders.insert(&f); f.addMsg(this);}void Message::remove(Folder &f){ folders.erase(&f); f.remMsg(this);}void Message::add_to_Folders(const Message &m){ for (auto &f : m.folders) f->addMsg(this);}Message::Message(const Message &m) :contents(m.contents), folders(m.folders){ add_to_Folders(m);}void Message::remove_from_Folders(){ for (auto f : folders) f->remMsg(this);}Message::~Message(){ remove_from_Folders();}Message& Message::operator=(const Message rhs){ remove_from_Folders(); contents = rhs.contents; folders = rhs.folders; add_to_Folders(rhs); return *this;}void swap(Message &lhs, Message &rhs){ set<Folder*> lfolders = lhs.folders; set<Folder*> rfolders = rhs.folders; for (auto f : rhs.folders) f->remMsg(&rhs); for (auto f : lhs.folders) f->remMsg(&rhs); lhs.folders = rhs.folders; rhs.folders = lhs.folders; swap(lhs.contents, rhs.contents); for (auto f : lhs.folders) f->addMsg(&lhs); for (auto f : rhs.folders) f->addMsg(&rhs);}
C++primer 練習13.36