了解了remove_Msg_from_Folders的工作之后,我们来看看为什么赋值操作符首先要检查对象是否不同。赋值时需删除左操作数,并在撤销左操作数的成员之后,将右操作数的成员赋值给左操作数的相应成员。如果对象是相同的,则撤销左操作数的成员也将撤销右操作数的成员!
即使对象赋值给自己,赋值操作符的正确工作也非常重要。保证这个行为的通用方法是显式检查对自身的赋值。
5、remove_Msg_from_Folders成员
void Message::remove_Msg_from_Folders()
{
for (set
::iterator beg = folders.begin();
beg != folders.end(); ++beg)
{
(*beg) -> remMsg(this);
}
}
6、Message析构函数
Message::~Message()
{
remove_Msg_from_Folders();
}
有了remove_Msg_from_Folders函数,编写析构函数将非常简单。我们调用remove_Msg_from_Folders函数清除folders,系统自动调用string析构函数释放contents,自动调用set析构函数清除用于保存folders成员的内存,因此,Message析构函数唯一要做的是调用remove_Msg_from_Folders。
【最佳实践:】
赋值操作符通常需要做复制构造函数函数和析构函数也要完成的工作。在这种情况下,通用工作应该放在private实用函数中。
//P419 习题13.17
//under the private labor
void addFldr(Folder *f)
{
folders.insert(f);
}
void remFldr(Folder *f)
{
folders.erase(f);
}
//习题13.19
void Message::save(Folder &f)
{
folders.insert(&f);
f.addMsg(this);
}
void Message::remove(Folder &f)
{
folders.erase(&f);
f.remMsg(this);
}
//拓展:完成完整的类Folder和Message,完成习题13.16~13.19内容 //in Folder.h #ifndef FOLDER_H_INCLUDED #define FOLDER_H_INCLUDED #include#include class Message; class Folder { public: Folder() {} ~Folder(); void addMsg(Message *); void remMsg(Message *); private: std::set messages; void remove_Fldr_form_Messages(); }; class Message { public: Message(const std::string &str = ""):contents(str) {}; Message(const Message &); Message &operator=(const Message &); ~Message(); void save(Folder &); void remove(Folder &); void addFldr(Folder *); void remFldr(Folder *); private: std::string contents; std::set folders; void put_Msg_in_Folders(const std::set &); void remove_Msg_from_Folders(); }; #endif // FOLDER_H_INCLUDED
//in Folder.cpp #include "Folder.h" #includeusing namespace std; Folder::~Folder() { remove_Fldr_form_Messages(); } void Folder::addMsg(Message *rhs) { messages.insert(rhs); } void Folder::remMsg(Message *rhs) { messages.erase(rhs); } void Folder::remove_Fldr_form_Messages() { for (std::set ::const_iterator beg = messages.begin(); beg != messages.end(); ++beg) { (*beg) -> remFldr(this); } } Message::Message(const Message &m):contents(m.contents),folders(m.folders) { put_Msg_in_Folders(folders); } Message &Message::operator=(const Message &rhs) { if (&rhs != this) { remove_Msg_from_Folders(); contents = rhs.contents; folders = rhs.folders; put_Msg_in_Folders(rhs.folders); } return *this; } Message::~Message() { remove_Msg_from_Folders(); } void Message::put_Msg_in_Folders(const set &rhs) { for (set ::const_iterator beg = rhs.begin(); beg != rhs.end(); ++beg) { (*beg) -> addMsg(this); } } void Message::remove_Msg_from_Folders() { for (set ::iterator beg = folders.begin(); beg != folders.end(); ++beg) { (*beg) -> remMsg(this); } } void Message::save(Folder &f) { folders.insert(&f); //更新Message所属的目录 f.addMsg(this); //更新目录 } void Message::remove(Folder &f) { folders.erase(&f); //更新Message所属的目录 f.remMsg(this); //更新目录 } void Message::addFldr(Folder *f) { folders.insert(f); } void Message::remFldr(Folder *f) { folders.erase(f); }