消息处理实例

来源:互联网 发布:天猫魔盒哪个软件好 编辑:程序博客网 时间:2024/04/29 11:43


#include "Folder.h"
#include <iostream>
using std::cerr; using std::endl;
using std::set; using std::string; using std::vector;
#include <string>
#include <set>
#include <vector>
class Folder;
class Message {
    friend class Folder;
public:
    // folders is initialized to the empty set automatically
    Message(const std::string &str = ""):
                  contents (str) { } 
    // copy control: we must manage pointers to this Message
    // from the Folders pointed to by folders
    Message(const Message&);
    Message& operator=(const Message&);
    ~Message(); 

    // add/remove this Message from specified Folder's set of messages
    void save(Folder&);  
    void remove(Folder&);

    std::vector<Folder*> get_folders(); // return list of folders
                               // in which this message resides
    std::string print_message() { return contents; }
    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   本消息出现在哪些folder中
// 消息和folder的关系是多对多的。
    // Utility functions used by copy constructor, assignment, and destructor:
    // Add this Message to the Folders that point to the parameter
    void put_Msg_in_Folders(const std::set<Folder*>&);
    // remove this Message from every Folder in folders
    void remove_Msg_from_Folders();

    // used by Folder class to add self to this Message's set of Folder's
    void addFldr(Folder *f) { folders.insert(f); }//消息所在的folder将会在消息插入folder的同时,将这个folder插入folder集中来
    void remFldr(Folder *f) { folders.erase(f); }
};
Message::Message(const Message &m):
    contents(m.contents), folders(m.folders)
{
    // add this Message to each Folder that points to m
    put_Msg_in_Folders(folders);  //由于这个消息的指针出现在很多folder中,所以复制的时候需要将有关这个消息的所出现的folder
}
 Message& Message::operator=(const Message &rhs)
{
    if (&rhs != this) {
        remove_Msg_from_Folders(); // update existing Folders
        contents = rhs.contents;   // copy contents from rhs
        folders = rhs.folders;     // copy Folder pointers from rhs
        // add this Message to each Folder in rhs
        put_Msg_in_Folders(rhs.folders);
    }
    return *this;
}
 Message::~Message()
{
    remove_Msg_from_Folders();//撤销这个消息时,需要更新所有的folder
}
 // add this Message to Folders that point to rhs
void Message::put_Msg_in_Folders(const set<Folder*> &rhs)
{
    for(std::set<Folder*>::const_iterator beg = rhs.begin();
                                     beg != rhs.end(); ++beg)
        (*beg)->addMsg(this);  // *beg points to a Folder
}
// remove this Message from corresponding Folders
void Message::remove_Msg_from_Folders()
{
    // remove this message from corresponding folders
    for(std::set<Folder*>::const_iterator beg =
          folders.begin(); beg != folders.end(); ++beg)
        (*beg)->remMsg(this);  // *beg points to a Folder
}
void Message::save(Folder &f)
{
    // add f to Folders and this Message to f's list of Messages
    folders.insert(&f); 
    f.addMsg(this);
}

void Message::remove(Folder &f)
{
    // remove f from Folders and this Message from f's list of Messages
    folders.erase(&f);
    f.remMsg(this);
}
class Folder {
    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() { } // defaults ok

    void save(Message&); // add this message to folder
    void remove(Message&); // remove this message from this folder
   
    // don't reveal implementation because it's likely to change
    // also better to copy than ref to the internal data structure so
    // have a copy to operate on not the actual contents is safer
    std::vector<Message*> messages(); // return list of messages in this folder
    void debug_print(); // print contents and it's list of Folders,
private:
    typedef std::set<Message*>::const_iterator Msg_iter;
    std::set<Message*> msgs;  // messages in this folder

    void copy_msgs(const std::set<Message*>&);// add this Folder to each Message
    void empty_msgs();           // remove this Folder from each Message
    void addMsg(Message *m) { msgs.insert(m); }
    void remMsg(Message *m) { msgs.erase(m); }
};
Folder::Folder(const Folder &f)
{
    copy_msgs(f.msgs);  // add this Folder to each Message in f.msgs
}
void Folder::copy_msgs(const set<Message*> &m)
{
    for (Msg_iter beg = m.begin(); beg != m.end(); ++beg)
        (*beg)->save(*this);   // add this Folder to each Message
}

Folder& Folder::operator=(const Folder &f)
{
    if (&f != this) {
        empty_msgs();  // remove this folder from each Message in msgs
        copy_msgs(f.msgs); // add this folder to each Message in msgs
    }
    return *this;
}
Folder::~Folder()
{
    empty_msgs();
}
void Folder::empty_msgs()
{
    Msg_iter it = msgs.begin();
    while (it != msgs.end()) {
        Msg_iter next = it;
        ++next;                // remember next element in msgs
        (*it)->remove(*this);
        it = next;
    }
}

void Folder::save(Message &m)
{
    // add m and add this folder to m's set of Folders
    msgs.insert(&m);
    m.addFldr(this);//不但要将m 插入到folder中,同时建立本消息与folder的关联,让本消息知道它已被插入到哪些folder
}

void Folder::remove(Message &m)
{
    // erase m from msgs and remove this folder from m
    msgs.erase(&m);
    m.remFldr(this);
}

vector<Folder*> Message::get_folders()
{
    return vector<Folder*>(folders.begin(), folders.end());
}

vector<Message*> Folder::messages()
{
    return vector<Message*>(msgs.begin(), msgs.end());
}

void Folder::debug_print()
{
    cerr << "Folder contains " << msgs.size() << " messages" << endl;
    int ctr = 1;
    for (Msg_iter beg = msgs.begin(); beg != msgs.end(); ++beg)
        cerr << "Message " << ctr++ << ":\n\t"
             << (*beg)->print_message() << endl;
}

void Message::debug_print()
{
    cerr << "Message:\n\t" << contents << endl;
    cerr << "Appears in " << folders.size() << " Folders" << endl;
}

原创粉丝点击