练习13.33
为什么Message的成员save和remove的参数是一个Folder&?
为什么我们不讲参数定义为Folder或是const Folder?
解答:
因为这里要对原始Folder对象进行插入或删除的操作,所以使用的是Floder&。(当然也可以使用指针,不过指针需要有一个复制过程,没有引用性能好)
直接定义为Folder不会对原始的Floder对象有任何改动;同样的,const Folder会引发编译错误,因为这里对Floder进行了插入和删除,const属性是不会让我们这样做的。
练习13.34
编写本节所描述的Message。
解答:
在informit.com/title/0321714113的页面中,有书中源码的下载,同样也包括Message的整体实现。
class Folder;
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); }
};
// declaration for swap should be in the same header as Message itself
void swap(Message&, Message&);
这里就将头文件中内容贴出来
练习13.35
如果Message使用合成拷贝控制成员,将会发生什么?
解答:
将会把本Message对象的指针添加到每个Folder中。
练习13.36
设计并实现对应的Folder类。此类应该保存一个指向Folder中包含的Message的set。
解答:
在informit.com/title/0321714113的页面中,有书中源码的下载,同样也包括Folder的整体实现。
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.37
为Message类添加成员,实现向folders添加或删除一个给定的Folder*。这两个成员类似Folder类的addMsg和remMsg操作。
解答:
// 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); }
练习13.38
我们并未使用拷贝和交换方式来设计Message的赋值运算符。你认为其原因是什么?
解答:
Message中的swap是为了避免对contents和folders成员进行不必要的拷贝,而实现的。
Message的赋值运算符必须执行拷贝的工作。
所以,这里并未使用swap。