拷贝控制示例

 拷贝控制示例包含两个对象Message和Folder,类似于邮件中一个Message和文件夹Folder的关系:一个Message隶属于一个和多个Folder,一个Folder中包含0个或者多个Message。

这样看来,Message和Folder的关系,可以认为是等价的(忽略Folder的0对多)。他们之间的关系操作,包括如下几个:

  1. 拷贝操作:拷贝后副本与源独立,副本拥有源的所有内容和包含关系,并需要在所有关联的对象中建立关联
  2. 销毁操作:从与之关联的对象中,删除与本对象的关系
  3. 增加关系(save):添加一条新的关联
  4. 删除关系(remove):删除一条关系
class Message
{
    friend class Folder;
public:
    explicit Message(const std::string &str = "") :contents(str)
    {
    }
    Message(const Message& msg) :contents(msg.contents), folders(folders)
    {
        add_to_Folders(msg);
    }
    //如果使用拷贝并交换方式会增加两个私有函数的调用次数
    Message& operator=(const Message& msg)
    {
        remove_from_Folders();//先删除Folder中存储的msg引用
        contents = msg.contents;
        folders = msg.folders;
        add_to_Folders(msg);//再将folders记录中的folder中添加msg
        return *this;
    }
    ~Message()
    {
        remove_from_Folders();
    }
    void swap(Message &lhs, Message &rhs)
    {
        using std::swap;
        for (auto f : lhs.folders)
            f->remove(lhs);
        for (auto f : rhs.folders)
            f->remove(rhs);
        swap(lhs.folders, rhs.folders);
        swap(lhs.contents, rhs.contents);
        for (auto f : lhs.folders)
            f->save(lhs);
        for (auto f : rhs.folders)
            f->save(rhs);
    }
    void save(Folder& f)
    {
        folders.insert(&f);
        f.save(*this);
    }
    void remove(Folder&f)
    {
        folders.erase(&f);
        f.remove(*this);
    }
private:
    string contents;
    set<Folder*> folders;

    void add_to_Folders(const Message& msg)
    {
        for (auto f : msg.folders)
            f->save(*this);
    }
    void remove_from_Folders()
    {
        for (auto f : this->folders)
            f->remove(*this);
    }
};
class Folder
{
    friend class Message;
public:
    explicit Folder(const std::string &str = "") :folder_name(str)
    {
    }
    Folder(const Folder& folder) :folder_name(folder.folder_name), messages(messages)
    {
        add_to_Messages(folder);
    }
    //如果使用拷贝并交换方式会增加两个私有函数的调用次数
    Folder& operator=(const Folder& folder)
    {
        remove_from_Messages();//先删除Folder中存储的msg引用
        folder_name = folder.folder_name;
        messages = folder.messages;
        add_to_Messages(folder);//再将folders记录中的folder中添加msg
        return *this;
    }
    ~Folder()
    {
        remove_from_Messages();
    }
    void swap(Folder &lhs, Folder &rhs)
    {
        using std::swap;
        for (auto f : lhs.messages)
            f->remove(lhs);
        for (auto f : rhs.messages)
            f->remove(rhs);
        swap(lhs.messages, rhs.messages);
        swap(lhs.folder_name, rhs.folder_name);
        for (auto f : lhs.messages)
            f->save(lhs);
        for (auto f : rhs.messages)
            f->save(rhs);
    }
    void save(Message& msg)
    {
        messages.insert(&msg);
        msg.save(*this);
    }
    void remove(Message& msg)
    {
        messages.erase(&msg);
        msg.remove(*this);
    }
private:
    string folder_name;
    set<Message*> messages;

    void add_to_Messages(const Folder& folder)
    {
        for (auto f : folder.messages)
            f->save(*this);
    }
    void remove_from_Messages()
    {
        for (auto f : this->messages)
            f->remove(*this);
    }
};
原文地址:https://www.cnblogs.com/qiusuo/p/5099335.html