拷贝控制
有时候我们需要两个类对象互相关联,当其中一个对象修改后也要关联修改另一个,用这个例子说明拷贝控制的案例。我们有两个类,Message类表示信息类,Folder类表示文件夹类,Message类里有成员folders表示其所属于哪些文件夹。Folder类有成员messages表示其包含哪些messages,所以Folder和Message之间是互相包含,多对多的关系。
同时我们要考虑Message类的拷贝,赋值,销毁等操作,如何同步处理其关联的Folder类。
其关系图是这样的
1 | class Message |
Message类定义了构造函数,默认将本Message所属的Folder集合设置为空。同时提供了save和remove操作,将本Message保存给指定Folder以及从指定Folder中删除。两个私有函数在很多地方通用,所以提出来作为私有函数。
同样我们声明Folder类
1 | class Folder |
接下来我们实现Message类的添加和删除操作
1 | //将Message保存在指定Folder中 |
接下来我们实现folder的addMsg和remMsg操作
1 | //保存指定的msg |
上述代码完成了msg插入folder后两个类之间的关联逻辑,当msg之间拷贝构造时需要完成folder的拷贝
1 | //将本Message添加到参数msg的folder中 |
拷贝构造函数就是将参数message的成员拷贝给新生成的对象,然后通过add_to_Folders函数将本消息添加到m的folders中。
接下来实现析构函数,message析构时将folders遍历移除本message
1 | //从folders中的每个Folder删除本Message |
拷贝构造函数需要两个操作,将自身的folders中删除本msg,然后将=右侧的message的folders赋值给本msg,并且将本message添加到folders中。其实是融合了析构和拷贝构造的两个操作。
1 | // 拷贝赋值运算符 |
在有些时候会用到swap操作,比如sort排序等,我们也实现一个Message版本的swap
1 | void swap(Message &lhs, Message &rhs) |
同样的道理,为实现folders的拷贝构造我单独实现一个私有函数add_msgs,将其
1 | // 将f中的msgs添加到本folder中 |
实现folders的析构函数,同样我也实现了一个私有函数remove_msgs
1 | //删除folder中的所有msgs |
同样道理拷贝赋值运算符的重载逻辑是拷贝构造和析构的综合
1 | //拷贝赋值运算符 |
同样我们实现Folder的swap函数
1 | void swap(Folder &lf, Folder &rf) |
接下来我们写一个函数测试上述赋值,析构,构造是否存在问题
1 | void test_msgfolder() |
上面的测试函数,创建了三个Folder对象和两个Message对象,调用了对象的拷贝构造,拷贝赋值以及析构等操作,在主函数中调用测试函数,程序运行稳定。
总结
本文主要通过Folder和Message的示例,演示了拷贝构造和拷贝赋值的控制逻辑,在两个类互相引用的情况下如何保证代码高效稳定运行。
源码链接
https://gitee.com/secondtonone1/cpplearn
想系统学习更多C++知识,可点击下方链接。
C++基础