码迷,mamicode.com
首页 > 编程语言 > 详细

C++primer 练习13.36

时间:2016-04-13 18:46:23      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

#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);
}

 

C++primer 练习13.36

标签:

原文地址:http://www.cnblogs.com/csudanli/p/5387820.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!