练习13.33 为什么Message的成员save和remove的参数是一个Folder&?为什么我们不将参数定义为Folder或是const Folder&?
目的是从Folder中添加/删除Message。
定义Floder添加/删除的是Message的副本,不是对象本身,而const Folder&将使得不能删除对象。
练习13.34 编写本节所描述的Message。
(见13.37)
练习13.35 如果Message使用合成的拷贝控制成员,将会发什么?
当使用合成的拷贝构造函数,在我们拷贝一个Message时,得到的副本应该是与Message出现在相同的Floder。
定义自己版本的拷贝构造函数,才能将拷贝的对象插入原来的Folder中。
练习13.36 设计并实现对应的Folder类。此类应该保存一个指向Folder中包含的Message的set。
(见13.37)
练习13.37 为Message类添加成员,实现向folders添加或删除一个给定的Folder*。这两个成员类似Folder类的addMsg和remMsg操做。
// = 。=
#include <set>
#include <string>
using namespace std;
class Folder;
class Message {
friend class Folder;
friend void swap(Message &, Message &);
public:
explicit Message(const std::string &str = "") :contents(s) {}
Message (const Message&);
Message operator=(const Message&);
~Message();
void save(Folder&);
void remove(Folder&);
private:
std::string contents;
std::set<Folder*> folders;
void add_to_Folder(const Message&);
void remove_from_Folder();
};
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_Folder(const Message &m)
{
for (auto f : m.folders) {
f->addMsg(this);
}
}
Message::Message(const Message&m) :contents(m.contents), folders(m.folders)
{
add_to_Folder(m);
}
void Message::remove_from_Folder()
{
for (auto f : folders) {
f->remMsg(this);
}
}
Message::~Message()
{
remove_from_Folder();
}
Message& Message::operator=(const Message &rhs)
{
remove_from_Folder();
contents = rhs.contents;
folders = rhs.folders;
add_to_Folder(rhs);
return *this;
}
void swap(Message &lhs, Message &rhs)
{
for (auto f : lhs.folders) {
f->remMsg(&lhs);
}
for (auto f : rhs.folders) {
f->remMsg(&rhs);
}
swap(lhs.folders, rhs.folders);
swap(lhs.contents, rhs.contents);
for (auto f : lhs.folders) {
f->addMsg(&lhs);
}
for (auto f : rhs.folders) {
f->addMsg(&rhs);
}
}
class Folder {
friend void swap(Message&, Message&);
friend class Message;
public:
~Folder(); // remove self from Messages in msgs
Folder(const Folder&); // add new folder to each Message in msgs
Folder& operator=(const Folder&); // delete Folder from lhs messages
// add Folder to rhs messages
Folder(Folder&&); // move Messages to this Folder
Folder& operator=(Folder&&); // delete Folder from lhs messages
// add Folder to rhs messages
#ifdef DEFAULT_FCNS
Folder() = default; // defaults ok
#else
Folder() { } // msgs will be default initialized, which is what we want
#endif
void save(Message&); // add this message to folder
void remove(Message&); // remove this message from this folder
void debug_print(); // print contents and it's list of Folders,
private:
std::set<Message*> msgs; // messages in this folder
void add_to_Messages(const Folder&);// add this Folder to each Message
void remove_from_Msgs(); // remove this Folder from each Message
void addMsg(Message *m) { msgs.insert(m); }
void remMsg(Message *m) { msgs.erase(m); }
void move_Messages(Folder*); // move Message pointers to point to this Folder
};
练习13.38 我们并未使用拷贝并交换方式来设计Message的赋值运算符。你认为原因是什么?
拷贝操作要分配内存,提高程序的不安全性。
交换操作对两个已存在的资源进行交换,优先考虑。