1. Folder和Message的类设计
2. Messager.h
class Message {
friend void swap(Message&, Message&);
friend class Folder;
public:
// folders is implicitly initialized to the empty set
explicit Message(const std::string &str = ""):
contents(str) {
}
// copy control to manage pointers to this Message
Message(const Message&); // copy constructor
Message& operator=(const Message&); // copy assignment
~Message(); // destructor
Message(Message&&); // move constructor
Message& operator=(Message&&); // move assignment
// add/remove this Message from the specified Folder's set of messages
void save(Folder&);
void remove(Folder&);
void debug_print(); // print contents and it's list of Folders,
// printing each Folder as well
private:
std::string contents; // actual message text
std::set<Folder*> folders; // Folders that have this Message
// utility functions used by copy constructor, assignment, and destructor
// add this Message to the Folders that point to the parameter
void add_to_Folders(const Message&);
void move_Folders(Message*);
// remove this Message from every Folder in folders
void remove_from_Folders();
// used by Folder class to add self to this Message's set of Folder's
void addFldr(Folder *f) {
folders.insert(f); }
void remFldr(Folder *f) {
folders.erase(f); }
};
3. save和remove
void Message::save(Folder &f)
{
folders.insert(&f); // add the given Folder to our list of Folders
f.addMsg(this); // add this Message to f's set of Messages
}
void Message::remove(Folder &f)
{
folders.erase(&f); // take the given Folder out of our list of Folders
f.remMsg(this); // remove this Message to f's set of Messages
}
4. folder 相关
// add this Message to Folders that point to m
void Message::add_to_Folders(const Message &m)
{
for (auto f : m.folders) // for each Folder that holds m
f->addMsg(this); // add a pointer to this Message to that Folder
}
// remove this Message from the corresponding Folders
void Message::remove_from_Folders()
{
for (auto f : folders) // for each pointer in folders
f->remMsg(this); // remove this Message from that Folder
folders.clear(); // no Folder points to this Message
}
5. 拷贝构造
Message::Message(Message &&m): contents(std::move(m.contents))
{
move_Folders(&m); // moves folders and updates the Folder pointers
}
Message::Message(const Message &m):
contents(m.contents), folders(m.folders)
{
add_to_Folders(m); // add this Message to the Folders that point to m
}
6. 析构
Message::~Message()
{
remove_from_Folders();
}
7. 拷贝赋值
Message& Message::operator=(Message &&rhs)
{
if (this != &rhs) {
// direct check for self-assignment
remove_from_Folders();
contents = std::move(rhs.contents); // move assignment
move_Folders(&rhs); // reset the Folders to point to this Message
}
return *this;
}
Message& Message::operator=(const Message &rhs)
{
// handle self-assignment by removing pointers before inserting them
remove_from_Folders(); // update existing Folders
contents = rhs.contents; // copy message contents from rhs
folders = rhs.folders; // copy Folder pointers from rhs
add_to_Folders(rhs); // add this Message to those Folders
return *this;
}
8. swap
void swap(Message &lhs, Message &rhs)
{
using std::swap; // not strictly needed in this case, but good habit
// remove pointers to each Message from their (original) respective Folders
for (auto f: lhs.folders)
f->remMsg(&lhs);
for (auto f: rhs.folders)
f->remMsg(&rhs);
// swap the contents and Folder pointer sets
swap(lhs.folders, rhs.folders); // uses swap(set&, set&)
swap(lhs.contents, rhs.contents); // swap(string&, string&)
// add pointers to each Message to their (new) respective Folders
for (auto f: lhs.folders)
f->addMsg(&lhs);
for (auto f: rhs.folders)
f->addMsg(&rhs);
}
9. 移动赋值
// move the Folder pointers from m to this Message
void Message::move_Folders(Message *m)
{
folders = std::move(m->folders); // uses set move assignment
for (auto f : folders) {
// for each Folder
f->remMsg(m); // remove the old Message from the Folder
f->addMsg(this); // add this Message to that Folder
}
m->folders.clear(); // ensure that destroying m is harmless
}
【参考】
[1] 代码copyControl.h