Message处理消息,Folder存放Message消息,一个Message消息可以放入多个文件夹Folder,一个Folder可以存放多个Message
按照此种方式设置了Message类插入消息,移除消息,将消息放入所有文件夹,移除所有文件夹中的消息,Folder类存放消息,移除消息
class Folder; class Message { public: Message(const string str = ""); //构造函数 ~Message(void); //析构函数 Message(const Message& msg);//复制构造函数 Message& operator=(const Message & msg); //赋值操作符 int operator!=(const Message & msg); //!=操作符 int AddFolder(Folder*); //插入当前的文件夹集合中 int RemoveFolder(Folder*);//从当前的文件夹集合中移除 int SaveMsg(Folder &); //放入指定文件夹 int RemoveMsg(Folder &); //从指定文件夹删除 private: string contents; //信息正文 set<Folder*> folders; //当前消息所在文件夹的集合 int PutMsgToFolders(const set<Folder*>&); //将本条消息加入所有文件夹 int RemoveMsgFromFolder(); //将本条消息从所有文件夹移除 }; class Folder{ public: Folder(); ~Folder(); int AddMsg(Message*); //将消息加入当前文件夹 int RemoveMsg(Message*); //将消息移除当前文件夹 private: set<Message*> msgs; //当前文件夹消息的集合 };
Message::Message(const string str) :contents(str) { }这里用传递进来的str初始化contents,这里使用了默认参数,所以也可以当做默认构造函数,folders会调用set的默认构造函数进行初始化为空集
Message::Message(const Message& msg) :contents(msg.contents),folders(msg.folders) { PutMsgToFolders(msg.folders); //默认合成的复制构造函数不能完成 }这里需要复制类成员,同时需要将当前消息的指针加入到所有的文件夹集合中,因为默认的合成函数并不能完成后面这一部分,所以必须自己定义复制构造函数。
Message& Message::operator=(const Message& msg) { //if (*this != msg); if ( &msg != this) { //移除与重新加入默认合成的赋值操作符也不能完成 if (!RemoveMsgFromFolder())//从当前消息的文件夹集合中移除当前消息的指针 { contents = msg.contents; folders = msg.folders; PutMsgToFolders(msg.folders);//将当前消息的指针加入到msg.folders集合的每一个文件夹中 } } return *this; }这里先进行了判断,C++Primer第四版中这样解释:“如果对象是相同的,则撤销左操作成员的同时也将撤销右操作数成员”,但是根据我的理解其实撤销的并不是是真正的左操作数,而是folders集中的指向当前消息的指针,当前消息下的folders集合并没有被删除,所以可以通过这个folders集合再重建每个folder下的消息指针,只不过就不止这些代码了。其他的就与复制构造函数相同了
int Message::AddFolder(Folder *pFolder) { pair< set<Folder*>::iterator, bool > pr; pr = folders.insert(pFolder); return pr.second; } int Message::RemoveFolder(Folder *pFolder) { return folders.erase(pFolder); }第一个函数主要进行了判断,插入是否成功,一个为key的类型,第二个为map的值,验证second的值就可以知道是否成功;第二个函数主要用来移除当前元素,这里返回值其实是删除了多少个,这里我进行了判断,即使删除一个也是成功的。
int Message::SaveMsg(Folder &rhs) { if(AddFolder(&rhs)) { rhs.AddMsg(this); return 0; } return -1; } int Message::RemoveMsg(Folder &rhs) { if (RemoveFolder(&rhs)) { rhs.RemoveMsg(this); return 0; } return -1; }这里其实是先加入的文件夹,再加入的消息,其实应该是相反的,考虑到没有多大影响没有更改
Message::~Message(void) { RemoveMsgFromFolder(); //所有指针的集合必须析构函数来完成 //folders.clear(); }这里主要是移除文件夹中指向当前消息的指针,默认合成析构函数会调用string的析构函数释放contents,再调用set析构函数释放folders集合内的成员
Folder类与以上类似,不再陈述,如下:
Folder::Folder() { } Folder::~Folder() { msgs.clear(); //清除当前所有的消息 } /*描述:将消息加入文件夹 *参数:传入的是Message指针 *返回值:True :插入成功 False:插入失败 */ int Folder::AddMsg(Message* pMsg) { pair< set<Message*>::iterator, bool > pr; pr = msgs.insert(pMsg); return pr.second; } /*描述:将消息从文件夹移除 *参数:传入的是Message指针 *返回值:1:移除成功 False:移除失败 */ int Folder::RemoveMsg(Message* pMsg) { return msgs.erase(pMsg); }
原文:http://blog.csdn.net/comwise/article/details/19491149