• C++primer 练习13.36


    #pragma once
    #include<string>
    #include<set>
    using namespace std;
    
    class Message
    {
        friend class Folder;
        friend void swap(Message &lhs, Message &rhs);
    public:
        explicit Message(const string &str=""):contents(str){}
        Message(const Message&);
        Message& operator=(const Message);//采用非引用类型,实现自赋值情况出现时,也能成功,但多了一次拷贝构造
        ~Message();
        void save(Folder &);
        void remove(Folder &);
    private:
        string contents;
        set<Folder*> folders;
        void add_to_Folders(const Message&);
        void remove_from_Folders();
    };
    
    class Folder
    {
    public:
        Folder(const Folder&);//拷贝构造函数
        Folder& operator=(const Folder);//拷贝赋值运算符,采用非引用类型,实现出现自赋值情况时,也能成功,但多了一次拷贝构造
        ~Folder();                //析构函数
        void addMsg(Message *);   //添加message
        void remMsg(Message *);   //去除message
    private:
        set<Message*> Mes;
        void addAllMsg();        //拷贝构造函数和拷贝赋值预算符的辅助函数
        void removeAllMsg();     //拷贝赋值运算符和析构函数的辅助函数
    };
    
    void Folder::addMsg(Message *m)
    {
        if(Mes.find(m)==Mes.end())//防止在调用m->save(*this)时的从复插入(虽然重复插入对于set来说没什么关系)
            Mes.insert(m);
        if (m->folders.find(this) == m->folders.end())//给递归调用一个结束条件,防止无限调用
            m->save(*this);
    }
    
    void Folder::remMsg(Message *m)
    {
        if (Mes.find(m) != Mes.end())//防止在调用m->remove(*this)时的从复删除(虽然重复删除对于set来说没什么关系)
            Mes.erase(m);
        if (m->folders.find(this) != m->folders.end())//给递归调用一个结束条件,防止无限调用
            m->remove(*this);
    }
    
    void Folder::addAllMsg()        //拷贝构造函数和拷贝赋值预算符的辅助函数
    {
        for (auto &m : Mes)         //对Mes集合中的每一个指针对象都调用save()函数
            m->save(*this);
    }
    
    Folder::Folder(const Folder &f)
    {
        Mes = f.Mes;              //将f中数据成员拷贝过来
        addAllMsg();              //调用addALLMsg将这个Folder添加到所有对应的message中去
    }
    
    void Folder::removeAllMsg()   //拷贝赋值运算符和析构函数的辅助函数
    {
        for (auto &m : Mes)       //对Mes集合中的每一个指针对象都调用remover()函数
            m->remove(*this);
    }
    
    
    Folder& Folder::operator=(const Folder f)//采用非引用类型是为了保护出现自赋值的情况时,也能正常运行
    {
        removeAllMsg();          //将数据成员中所包含的所有message都调用remove()函数,实现删除这个文件夹的作用
        Mes = f.Mes;             //将新的数据成员拷贝过来
        addAllMsg();             //将数据成员中所包含的所有message都调用remover()函数,完成为这个文件夹赋值右侧文件夹的步骤
        return *this;
    }
    
    Folder::~Folder()
    {
        removeAllMsg();         //将数据成员中所包含的所有message都调用remove()函数,实现删除这个文件夹的作用
    }
    
    
    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 &m)
    {
        for (auto &f : m.folders)
            f->addMsg(this);
    }
    
    Message::Message(const Message &m) :contents(m.contents), folders(m.folders)
    {
        add_to_Folders(m);
    }
    
    void Message::remove_from_Folders()
    {
        for (auto f : folders)
            f->remMsg(this);
    }
    
    Message::~Message()
    {
        remove_from_Folders();
    }
    
    Message& Message::operator=(const Message rhs)
    {
        remove_from_Folders();
        contents = rhs.contents;
        folders = rhs.folders;
        add_to_Folders(rhs);
        return *this;
    }
    
    void swap(Message &lhs, Message &rhs)
    {
        set<Folder*> lfolders = lhs.folders;
        set<Folder*> rfolders = rhs.folders;
        for (auto f : rhs.folders)
            f->remMsg(&rhs);
        for (auto f : lhs.folders)
            f->remMsg(&rhs);
        lhs.folders = rhs.folders;
        rhs.folders = lhs.folders;
        swap(lhs.contents, rhs.contents);
        for (auto f : lhs.folders)
            f->addMsg(&lhs);
        for (auto f : rhs.folders)
            f->addMsg(&rhs);
    }
  • 相关阅读:
    揭开正则表达式的神秘面纱
    海量数据库的查询优化及分页算法方案
    ASP.NET纯数字验证码
    ASP.NET四种页面导航方式之比较与选择
    C#数据结构之队列
    if exists
    使用tfs online做代码片段笔记管理
    强制删除数据库
    C# GetType()
    TreeView
  • 原文地址:https://www.cnblogs.com/csudanli/p/5387820.html
Copyright © 2020-2023  润新知