#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 *); //去除message private: 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); }