示例内容
建立应用在电子邮件中的两个类,Message负责保存消息,Folder保存message的路径,用set存放指针来实现,Message需要支持赋值、拷贝等操作

Message类

class Massage
{
    friend class Folder;
public:
    explicit Message(const std::string &str = ''):contents(str)
    {};//包含默认隐式初始化的构造函数
    Message(const Message&);//拷贝构造函数
    Message& operator=(const Message&);//重载运算符
    ~Message();//析构函数
    void save(Folder&);
    void remove(Folder&);//向文件夹中添加Message的操作
private:
    std::string contents;//消息文本数据成员
    std::set<Folder*> folders;//包含本message的folder文件夹的指针集合
    void add_to_Folders(const Massage&);//向Folder中添加Message
    void remove_from_Folders();//从Folders中删除Massage
}

Message::save(Folder &f)
{
    folder.insert(f);
    f.addMsg(this);//在Folder和Message的folder中添加Message
}

Message::remove(Folder &f)
{
    folder.erase(f);
    f.remMsg(this);//在Folder和Message的folder中移除Message
}

Message类的拷贝控制成员
当我们拷贝一个Message时,副本Message应当与原Message在同一个文件夹,所以要向每个具有原Message的文件夹中都添加副本的指针,定义一个新函数完成这一工作

void Message::add_to_Folders(const Message &m)
{
    for(auto f:m.folders)
    {
        f->addMsg(this);//遍历原Message的folders容器中存放的Folder指针,解引用并调用这些指针指向的Folder的addMsg函数,在这些Folder中存放新副本的指针
    }
}

解决文件夹的问题后需要解决拷贝原Message的问题

Message::Message(const Message &m):contents(m.contents), folders(m.folders)
{
    add_to_Folders(m);//调用上面定义的函数,进行添加文件夹的操作
}

Message的析构函数

void Message::remove_from_Folders()
{
    for (auto f:folders)
        f->remMsg(this);
}
Message::~Message()
{
    remove_from_Folders();
}

Message的拷贝赋值运算符
赋值运算符要解决自赋值的问题,本例采用先删除再增加的方式

Message::Message::operator=(const Message &rhs)
{
    remove_from_Folders();
    contents = rhs.contents;
    folders = rhs.folders;
    add_to_Folders(rhs);
    return *this;
}

Message的swap函数
采用两边扫描,首先扫描并删除,然后swap,然后再添加回去

void swap(Message &lhs, Message &rhs)
{
    using std::swap;
    for(auto f:lhs.folders)
        f->remMsg(&lhs);
    for(auto f:rhs.folders)
        f->addMsg(&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);
}