拷贝控制示例

  实现二个类,一个是Message,另一个是Folder;类似于消息和消息目录,每个Message对象可以出现在多个Folder中。但是,任意给定的Message的内容只有一个副本。其结构依赖:为了记录Message位于哪些Folder中,每个Message都会保存一个它所在Folder的指针的set,同样的,每个Folder都保存一个它保存一个它包含的Message的指针的set。

  首先是Message的头文件:

  1#ifndef _MESSAGE_                              
  2 #define _MESSAGE_ 
  3 #include <set>
  4 #include <string>
  5 #include <iostream>
  6 class Folder;
  7 using namespace std;
  8 class Message
  9 {
 10     friend class Folder;
 11     public:
 12         //默认构造函数
 13         Message()
 14         {}
 15         //带一个string类型的构造函数
 16         Message(const std::string &str)
 17             :msg(str)
 18         {}
 19 
 20         //析构函数
 21         ~Message();
 22 
 23         //拷贝构造函数
 24         Message(const Message &m);
 25 
 26         //赋值函数
 27         Message &operator=(const Message &m);
 28 
 29         //向指定目录保存信息
 30         void save(Folder &f);
 31 
 32         //从指定目录删除信息
 33         void remove(Folder &f);
 34         void show_msg();
 35 
 36     private:
 37         string msg;
 38         std::set<Folder *> folder;
 39         //因为赋值运算函数要执行拷贝构造函数和>    析构函数都要做的工作,这种情况,将公共工作放在p    rivate中作为工具函数完成
 40         void add_to_folder(const Message &m);
 41         void remove_from_folder();
 42 };
 43 
 44 
 45 #endif  /*_MESSAGE_*/

  然后是Message的cpp文件:

  1 #include "Message.h"
  2 #include "Folder.h"
  3 
  4 void Message::show_msg()
  5 {
  6     cout << msg << " ";
  7     for(auto &item: folder){
  8             cout << item << " ";
  9     }
 10 }
 11 
 12 //save操作
 13 void Message::save(Folder &f)
 14 {
 15     folder.insert(&f);
 16     f.addmsg(*this);   
 17 }
 18 
 19 //remove操作
 20 void Message::remove(Folder &f)
 21 {
 22     folder.erase(&f);
 23     f.removemsg(*this);
 24 }
 25 
 26 //每个m的Folder*指针添加指向此Message的Message*指针
 27 void Message::add_to_folder(const Message &m)                    
 28 {
 29     for(auto &item: m.folder){
 30             item->addmsg(*this);
 31     }
 32 }
 33 
 34 //拷贝构造函数
 35 Message::Message(const Message &m)
 36     :msg(m.msg), folder(m.folder)
 37 {
 38     add_to_folder(m);
 39 }
 40 
 41 //在每个Folder中删除指向此Message的指针
 42 void Message::remove_from_folder()
 43 {
 44     for(auto &item: folder){
 45         item->removemsg(*this);
 46     }
 47 }
 48 
 49 //析构函数
 50 Message::~Message()
 51 {
 52     remove_from_folder();
 53 }
 54 
 55 //赋值运算
 56 Message& Message::operator=(const Message &m)
 57 {
 58     remove_from_folder();
 59     msg = m.msg;
 60     for(auto &item: m.folder){
 61             folder.insert(item);
 62     }
 63     add_to_folder(*this);
 64     return *this;
 65 }

  Folder的头文件

 1 #ifndef _FOLDER_                                                 
  2 #define _FOLDER_ 
  3 #include <set>
  4 #include <string>
  5 #include <iostream>
  6 class Message;
  7 
  8 using namespace std;
  9 
 10 class Folder
 11 {
 12     friend class Message;
 13     public:
 14         //默认构造函数
 15         Folder()
 16         {}
 17 
 18         //析构函数
 19         ~Folder();
 20 
 21         //拷贝构造函数
 22         Folder(const Folder &f);
 23 
 24         //赋值函数
 25         Folder &operator=(const Folder &f);
 26 
 27         void addmsg(Message &m);
 28         void removemsg(Message &m);
 29         void show_folder();
 30     private:
 31         std::set<Message *> folder;
 32         void add_to_message(const Folder &f);
 33         void remove_from_message();
 34 };
 35 
 36 
 37 #endif  /*_FOLDER_*/

  然后是Folder的cpp文件:

  1 #include "Folder.h"                                                        
  2 #include "Message.h"
  3 void Folder::show_folder()
  4 {
  5     for(auto &item: folder){
  6             cout << item << " ";
  7     }
  8     cout << endl;
  9 }
 10 
 11 //添加Message指针
 12 void Folder::addmsg(Message &m)
 13 {
 14     folder.insert(&m);
 15 }
 16 
 17 //删除Message指针
 18 void Folder::removemsg(Message &m)
 19 {
 20     folder.erase(&m);
 21 }
 22 
 23 //对f的set中的每个Message添加到此目录的指针
 24 void Folder::add_to_message(const Folder &f)
 25 {
 26     for(auto &item: f.folder){
 27             item->save(*this);
 28     }
 29 }
 30 
 31 //拷贝构造函数
 32 Folder::Folder(const Folder &f)
 33     :folder(f.folder)
 34 {
 35     add_to_message(f);
 36 }
 37 
 38 //对set中的Message删除指向此目录的指针
 39 void Folder::remove_from_message()
 40 {
 41     for(auto &item: folder){
 42             item->folder.erase(this);
 43     }
 44 }
 45 
 46 //析构函数
 47 Folder::~Folder()
 48 {
 49     remove_from_message();
 50 }
 51 
 52 //赋值运算
 53 Folder& Folder::operator=(const Folder &f)
 54 {
 55     remove_from_message();
 56     for(auto &item: f.folder){
 57             folder.insert(item);
 58     }
 59     add_to_message(*this);
 60     return *this;
 61 }
 62                                  

  这就是拷贝控制的示例。

  ps:拷贝赋值运算符通常执行拷贝构造函数和析构函数中也要做的工作。这种情况下,公共的工作应该放在private的工具函数中完成。

 

  

posted @ 2015-03-30 16:05  bigshowxin  阅读(118)  评论(0编辑  收藏  举报