拷贝控制示例

  实现二个类,一个是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的工具函数中完成。

  

时间: 2024-11-08 23:45:18

拷贝控制示例的相关文章

【足迹C++primer】45、拷贝控制示例

拷贝控制示例 那么接下来尽情欣赏这个案例吧!!! /** * 功能:拷贝控制示例 * 时间:2014年7月14日10:57:39 * 作者:cutter_point */ #include<iostream> #include<set> #include<vector> #include<string> using namespace std; class Folder; /** Message类 */ class Message { friend void

【C++ Primer 第十三章】4. 拷贝控制示例

拷贝控制示例 1 #include<iostream> 2 #include<string> 3 #include<set> 4 using namespace std; 5 6 class Folder; 7 8 class Message { 9 friend void swap(Message&, Message&); 10 friend class Folder; 11 public: 12 explicit Message(const stri

C++11(12):拷贝控制

拷贝构造函数的第一个参数必须是引用类型,此参数几乎总是const的引用.拷贝构造函数在几种情况下会隐式地使用.因此,拷贝构造函数不应该是explicit的 即使我们定义了其他构造函数,在没有拷贝构造函数时,编辑器也会为我们合成的.编辑器从给定对象中依次将每个非static成员拷贝到创建的对象中.每个成员决定了它使用何种方式进行拷贝.类调用拷贝构造函数,数组逐个拷贝,内置类型直接拷贝 string dots(10,'.')  //直接初始化 string noll_book="999999&quo

拷贝控制

当定义一个类时,我们显式地或隐式地指定在此类型的对象拷贝.移动.赋值和销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数(copy constructor).拷贝赋值运算符(copy-assignment operator).移动构造函数(move constructor).移动赋值运算符(move-assignment operator)和析构函数(destructor).拷贝和移动构造函数定义了当用同类型的另一个对象初始化本对象时做什么.拷贝和移动赋值运算符定义

C++学习之构造函数和拷贝控制--什么样的情况下才需要虚析构函数

什么样的情况下才需要虚析构函数? 类需要控制自己的对象执行一系列操作时发生什么样的行为,这些操作包括:创建(对象).拷贝.移动.赋值和销毁.在继承体系中,如果一个类(基类或其派生的类)没有定义拷贝控制操作,则编译器将自动的为其合成一个.即为合成的拷贝控制. 在基类的拷贝控制中,由于继承关系导致的最大影响就是:基类通常应该定义一个‘虚析构函数’.用以动态的分配继承体系中的对象. 如:类A,B,C,D有如下继承关系(代码1): 1 2 3 4 class A; class B:public A; c

C#实现防拷贝工具示例

思路是用加密程序 对硬盘号,cpu号和MAC号取出字符串并加密 产生一个序列号 每次程序启动后重新产生这个序列号并比对,如果一致则验证通过 using System;using System.Collections.Generic;using System.IO;using System.Management;using System.Text;using System.Management.Instrumentation; static string GetDeviceNumber() { s

基类和派生类中构造函数和拷贝控制

15.26 定义Quote和Bulk_quote的拷贝控制成员,令其与合成的版本行为一致.为这些成员以及其他构造函数添加打印状态的语句,使得我们能够知道正在运行哪个程序.使用这些类编写程序,预测程序将创建和销毁哪些对象.重复实验,不断比较你的预测和实际输出结果是否相同,直到预测完全准确再结束. Quote.h #ifndef QUOTE_H #define QUOTE_H #include<iostream> #include<string> using namespace std

C++中类的拷贝控制 与之相关的几个函数

转自:http://www.cnblogs.com/ronny/p/3734110.html 对于部分内容会在接下来的文章中详细介绍 1,什么是类的拷贝控制 当我们定义一个类的时候,为了让我们定义的类类型像内置类型(char,int,double等)一样好用,我们通常需要考下面几件事: Q1:用这个类的对象去初始化另一个同类型的对象. Q2:将这个类的对象赋值给另一个同类型的对象. Q3:让这个类的对象有生命周期,比如局部对象在代码部结束的时候,需要销毁这个对象. 因此C++就定义了5种拷贝控制

【c++】拷贝控制具体分析

我们可以定义拷贝操作,使类的行为看起来像一个值或者像一个指针,这取决于如何拷贝指针成员. 当我们拷贝一个像值的对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响,反之亦然.标准库容器和string类的行为像一个值. 当我们拷贝一个行为像指针的类的对象时,副本和原对象使用相同的底层数据,改变副本也会改变原对象,反之亦然. 一.行为像值的类 class HasPtr { public: HasPtr(const HasPtr&) :ps(new string(*p.ps), i(p.i