C++ Primer 学习笔记_56_类与数据抽象 --消息处理示例(二)

2014-11-24 12:27:00 · 作者: · 浏览: 1
给这个对象。最后,调用put_Msg_in_Folders将指向这个Message的指针 添加至指向rhs的每个 Folder中。

了解了remove_Msg_from_Folders的工作之后,我们来看看为什么赋值操作符首先要检查对象是否不同。赋值时需删除左操作数,并在撤销左操作数的成员之后,将右操作数的成员赋值给左操作数的相应成员。如果对象是相同的,则撤销左操作数的成员也将撤销右操作数的成员!

即使对象赋值给自己,赋值操作符的正确工作也非常重要。保证这个行为的通用方法是显式检查对自身的赋值。


5、remove_Msg_from_Folders成员

void Message::remove_Msg_from_Folders()
{
    for (set
  
   ::iterator beg = folders.begin();
            beg != folders.end(); ++beg)
    {
        (*beg) -> remMsg(this);
    }
}

  


6、Message析构函数

Message::~Message()
{
    remove_Msg_from_Folders();
}

有了remove_Msg_from_Folders函数,编写析构函数将非常简单。我们调用remove_Msg_from_Folders函数清除folders,系统自动调用string析构函数释放contents,自动调用set析构函数清除用于保存folders成员的内存,因此,Message析构函数唯一要做的是调用remove_Msg_from_Folders。


【最佳实践:】

赋值操作符通常需要做复制构造函数函数和析构函数也要完成的工作。在这种情况下,通用工作应该放在private实用函数中。

//P419 习题13.17
    //under the private labor
    void addFldr(Folder *f)
    {
        folders.insert(f);
    }
    void remFldr(Folder *f)
    {
        folders.erase(f);
    }

//习题13.19
void Message::save(Folder &f)
{
    folders.insert(&f);
    f.addMsg(this);
}

void Message::remove(Folder &f)
{
    folders.erase(&f);
    f.remMsg(this);
}

//拓展:完成完整的类Folder和Message,完成习题13.16~13.19内容
//in Folder.h
#ifndef FOLDER_H_INCLUDED
#define FOLDER_H_INCLUDED

#include 
  
   
#include 
   
     class Message; class Folder { public: Folder() {} ~Folder(); void addMsg(Message *); void remMsg(Message *); private: std::set
    
      messages; void remove_Fldr_form_Messages(); }; class Message { public: Message(const std::string &str = ""):contents(str) {}; Message(const Message &); Message &operator=(const Message &); ~Message(); void save(Folder &); void remove(Folder &); void addFldr(Folder *); void remFldr(Folder *); private: std::string contents; std::set
     
       folders; void put_Msg_in_Folders(const std::set
      
        &); void remove_Msg_from_Folders(); }; #endif // FOLDER_H_INCLUDED 
      
     
    
   
  

//in Folder.cpp
#include "Folder.h"
#include 
  
   
using namespace std;

Folder::~Folder()
{
    remove_Fldr_form_Messages();
}

void Folder::addMsg(Message *rhs)
{
    messages.insert(rhs);
}
void Folder::remMsg(Message *rhs)
{
    messages.erase(rhs);
}

void Folder::remove_Fldr_form_Messages()
{
    for (std::set
   
    ::const_iterator beg = messages.begin(); beg != messages.end(); ++beg) { (*beg) -> remFldr(this); } } Message::Message(const Message &m):contents(m.contents),folders(m.folders) { put_Msg_in_Folders(folders); } Message &Message::operator=(const Message &rhs) { if (&rhs != this) { remove_Msg_from_Folders(); contents = rhs.contents; folders = rhs.folders; put_Msg_in_Folders(rhs.folders); } return *this; } Message::~Message() { remove_Msg_from_Folders(); } void Message::put_Msg_in_Folders(const set
    
      &rhs) { for (set
     
      ::const_iterator beg = rhs.begin(); beg != rhs.end(); ++beg) { (*beg) -> addMsg(this); } } void Message::remove_Msg_from_Folders() { for (set
      
       ::iterator beg = folders.begin(); beg != folders.end(); ++beg) { (*beg) -> remMsg(this); } } void Message::save(Folder &f) { folders.insert(&f); //更新Message所属的目录 f.addMsg(this); //更新目录 } void Message::remove(Folder &f) { folders.erase(&f); //更新Message所属的目录 f.remMsg(this); //更新目录 } void Message::addFldr(Folder *f) { folders.insert(f); } void Message::remFldr(Folder *f) { folders.erase(f); }