复制控制例子 --参照《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函数中

 

                          

posted @ 2011-11-09 11:24  吴豆豆  阅读(609)  评论(0编辑  收藏  举报