13.33 save和remove需要把给定Folder的指针从folders中添加或删除,如果参数是Folder,则操作的是形参的指针,不是原始Folder的指针,必须用引用才能得到原始Folder的指针;另外还要将当前Message的指针从Folder的messages中添加或删除,就需要改变Folder的内容,因此不能用const。
13.34 头文件:Folder.h
#ifndef FOLDER_H
#define FOLDER_H
#include <set>
using namespace std;
class Folder;
class Message {
friend void swap(Message&, Message&);
friend class Folder;
public:
explicit Message(const string &str = ""):
contents(str) { }
Message(const Message&);
Message& operator=(const Message&);
~Message();
void save(Folder&);
void remove(Folder&);
void debug_print();
private:
string contents;
set<Folder*> folders;
void add_to_Folders(const Message&);
void remove_from_Folders();
void addFolder(Folder*);
void remFolder(Folder*);
};
class Folder {
friend void swap(Message&, Message&);
friend class Message;
public:
Folder() = default;
Folder(const Folder&);
Folder& operator=(const Folder&);
~Folder();
void save(Message&);
void remove(Message&);
void debug_print();
private:
set<Message*> messages;
void add_to_Messages(const Folder&);
void remove_from_Messages();
void addMsg(Message*);
void remMsg(Message*);
};
#endif
Folder.cc文件代码:
#include <utility>
#include <iostream>
#include <set>
#include <string>
#include "Folder.h"
using namespace std;
void swap(Message &lhs, Message &rhs)
{
using std::swap;
for (auto f : lhs.folders)
f->remMsg(&lhs);
for (auto f : rhs.folders)
f->remMsg(&rhs);
swap(lhs.contents, rhs.contents);
swap(lhs.folders, rhs.folders);
for (auto f : lhs.folders)
f->addMsg(&lhs);
for (auto f : rhs.folders)
f->addMsg(&rhs);
}
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 &msg)
{
for (auto f : msg.folders)
f->addMsg(this);
}
void Message::remove_from_Folders()
{
for (auto f : folders)
f->remMsg(this);
}
Message::Message(const Message &msg):
contents(msg.contents), folders(msg.folders)
{
add_to_Folders(msg);
}
Message::~Message()
{
remove_from_Folders();
}
Message&
Message::operator=(const Message &rhs)
{
contents = rhs.contents;
remove_from_Folders();
folders = rhs.folders;
add_to_Folders(rhs);
return *this;
}
void Message::addFolder(Folder *fp)
{
folders.insert(fp);
}
void Message::remFolder(Folder *fp)
{
folders.erase(fp);
}
void Message::debug_print()
{
cerr << "Message:\n\t" << contents << endl;
cerr << "Appears in " << folders.size() << " Folders" << endl;
}
void Folder::save(Message &m)
{
messages.insert(&m);
m.addFolder(this);
}
void Folder::remove(Message &m)
{
messages.erase(&m);
m.remFolder(this);
}
void Folder::addMsg(Message *m)
{
messages.insert(m);
}
void Folder::remMsg(Message *m)
{
messages.erase(m);
}
void Folder::add_to_Messages(const Folder &f)
{
for (auto m : f.messages)
m->addFolder(this);
}
void Folder::remove_from_Messages()
{
for (auto m : messages)
m->remFolder(this);
}
Folder::Folder(const Folder &f): messages(f.messages)
{
add_to_Messages(f);
}
Folder& Folder::operator=(const Folder &f)
{
remove_from_Messages();
messages = f.messages;
add_to_Messages(f);
return *this;
}
Folder::~Folder()
{
remove_from_Messages();
}
void Folder::debug_print()
{
cerr << "Folder contains " << messages.size() << " messages" << endl;
int ctr = 1;
for (auto m : messages)
cerr << "Message " << ctr++ << ":\n\t" << m->contents << endl;
}
13.35 拷贝Message,还需要将Message添加到每个Folder中,使用合成版本无法实现这个目的。
13.36 见13.34中Folder类的实现。
13.37 见13.34中addFolder和remFolder成员函数。
13.38 使用swap功能无误,但rhs创建,销毁并两次添加,删除是不必要的,效率低下,因此不使用swap函数实现。