• 复制控制例子 参照《C++ Primer》第415页消息处理示例


     

    一.场景:

    两个类:

    Folder类:

     表示一个目录,有一些指针成员指向该目录下的文件

    File类:

       表示一个文件,

    1)有一个string成员存储文件内容

    2)有Folder类型的成员指针集指向存有该文件的目录

    3)有一个save()remove()方法分别用于保存和移动。

    功能:(1)在创建的时候传入文本初始化文件的文本

         (2)在保存的时候传入目录指定文件所在的目录 (可保存在多个目录)

         (3)要求能复制、赋值、删除文件类

          

    如图:(简化)

     

    二.数据结构

    1.Folder: 只要有一些 指向 File类的指针即可

    2.File:  set <Folder*>:指针集来存储所在的目录

             string content :存储文本内容

    三.分析File

    1.功能:(考虑文件和目录之间的指针处理)

    1)写入内容(content):创建的时候

    2)保存文件类:保存在某个目录下

    3)复制文件类:在所有包含该文件的地方都要求有文件的副本

    4)删除文件类:在所有包含该文件的地方都要删掉

    2.特性:

      可保存在多个目录下,文件类记录了所在的目录。多个目录指向的是同一个文件。

      (考虑文件和目录之间的指针处理)

    3.功能实现:(文件和目录之间的指针处理) 

    (1)写入内容:(形参:内容)(构造函数实现)

       创建File类的时候写入内容,但是不指定在哪个目录(未保存)

    (2)保存(形参:目录)

     

         将file 类存入指定的目录FolderA中。在file类中的set<Folder*>添加FolderA,并在FolderA中添加指向该file类对象的指针。

     

    (3)删除文件类

    1. 要把包含B的目录中把指向的指针释放,还有B指向目录的指针也要释放掉

    如图:

     

     

    (4)复制文件类(复制 到B原先不存在))

         1.复制类成员(content , set<folder*> )到新对象 (合成的复制构造函数做的事情)

         2.set<folder*>中的 每一个folder*(目录)都必须添加一个指向新对象的指针

           (合成的复制构造函数不会做这一步)

    如图:

     

    \

       

    (5)赋值文件类(A复制到B(B原先存在)

    2.要把包含B的目录中把指向的指针删掉,还有B指向目录的指针也要释放掉(删除操作

    3.把的成员赋值给B(文本内容和指针集合)  -

    4.包含了的目录要添加指向的指针(现在目录可以从的新的指针集合中获取)(复制操作)

      可以看到:赋值操作是由删除(1)和复制(23)的操作合成的。

     

     

     

    四、实现File

    1、从前面的分析可以看到

    删除操作 --》析构函数

    复制操作--》复制构造函数

    赋值操作--》赋值操作符

    用到了复制控制的三个函数,而且编译器合成的函数无法满足需求,所以要用户自定义这三个函数。(注意,自定义析构函数后还是会调用合成的析构函数)

    2、实现:

    定义类File成员: string content, set<Folder*>folders;

    定义两个private函数:(注意赋值操作用到了删除和复制,所以删除和复制各用一个 private函数实现,以便多个成员函数调用)

     Put_File_In_Folder(const set<Folder*>folders);//把文件加入到相对于的目录集

     Remove_File_From_Folder();//从包含文件的目录集中删除该文件对象

     

    (1)析构函数:(对应删除操作)成员的释放由自动调用的析构函数完成

    File::~File()

    {

      Remove_File_From_Folders();

    }

    (2)复制构造函数(复制操作)

    File::File(const File &m)

    content(m.content),folders(m.folders)  //初始化列表

    {

     Put_File_In_Folder(folders);  //为目录集添加指向该类的指针

    }

     

    (3)赋值操作符重载(赋值操作)

    File & File::operator = (const File &rhs)

    {

    If (&hrs != this)

    {

    Remove_File_From_Folders();   //删除原来的指针

    Content = rhs.content;

    Folders = rhs.folders;

    Put_File_In_Folder(folders);     /为目录集添加指向该类的指针

    }

    }

     

    五、心得:

     要根据实际情况来判断是否要自定义复制控制操作,同时赋值操作符通知要做复制构造函数和析构函数要完成的工作,所以可以把通用的工作放在private函数中

     

                              

  • 相关阅读:
    Contains,Exists,Any,Count 比较是否存在某个元素
    RabbitMQ (十六) 消息队列的应用场景 (转)
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(四)
    RabbitMQ (十五) 镜像集群 + HAProxy1.7.8 负载均衡
    RabbitMQ (十四) 普通集群
    RabbitMQ (十三) 集群+单机搭建(window)
    (转) HA的几种方案
    RabbitMQ (十二) 消息确认机制
    RabbitMQ (十一) 消息确认机制
    VIM操作
  • 原文地址:https://www.cnblogs.com/gdutbean/p/2242256.html
Copyright © 2020-2023  润新知