C++primer 阅读点滴记录(一)
第十三章 复制控制:(copy control)
复制构造函数(copy constructor)
复制操作符(assignment operator)
ps: 什么时候需要显示的定义复制控制操作:类具有指针成员,一般情况使用默认的复制控制
有的类 需要禁止复制构造函数, iostream类就不允许复制
类必须显示的声明其复制构造函数为private
| 最佳实践: | 一般来说,最好显示或隐式定义默认构造函数和复制构造函数,只有不存在其他构造函数是才合成默认构造函数,如果定义了复制构造函数,也必须定义默认构造函数 |
//示例代码:
//copy constructor :
Sales_item(const Sales_item& orig):
isbn(orig.isbn),
units_sold(orig.units_sold),
revenue(orig.revenue){}
//assignment operator:
Sales_item& operator=(const Sales_items& rhs) Sales_item& Sales_item::operator=(const Sales_item& rhs){
isbn = rhs.isbn;
units_sold = rhs.units_sold;
revenue = rhs.revenue;
return *this;
}
| 注解: | 实际上,应该将复制和赋值两个操作看作一个单元。 如果需要其中一个,我们几乎也肯定需要另一个。 |
13.3 析构函数(destructor)
何时调用析构函数:
/*
* 撤销类对象时会自动调用析构函数
* 动态分配的对象只有在指向该对象的指针被删除时才撤销
*/
void destructor_test(){
Sales_item* p = new Sales_item;
{//new scope
Sales_item item(*p);//copy constructor copies *p into item
delete p;//destructor called on object pointed to by p
}//exit local scope; destructor called on item
}
| 提示: | 如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则。这个规则常称为三法则(rule of three),指的是如果需要析构函数,则需要所有这三个幅值控制成员。 |
| 注解: | 撤销内置类型成员或复合类型的成员没什么影响。 尤其是,合成析构函数并不删除指针成员所指向的对象。(ps:所以 有指针对象成员的类 需要析构函数,需要复制构造函数 赋值操作符) |
消息实例 演示复制控制
#ifndef MESSAGE_H
#define MESSAGE_H
#pragma once
#include <string>
#include <iostream>
#include <set> using namespace std; class Message; class Folder{
public:
Folder(const string& s):folder_name(s){}
Folder(const Folder&);
Folder& operator=(const Folder&);
~Folder(); void save(Message&);
void remove(Message&); void addMsg(Message*);
void remMsg(Message*);
private:
set<Message*> messages;
string folder_name; void put_Fldr_in_Message(const set<Message*>&);
void remove_Fldr_from_Message();
}; class Message
{
public:
Message(const string& str=""):contents(str){}
Message(const Message&);//复制构造函数
Message& operator=(const Message&);//赋值操作符
~Message(); void save(Folder&);
void remove(Folder&); void addFldr(Folder*);
void remFldr(Folder*);
private:
string contents; //actual message text
set<Folder*> folders;//folders that have this message
void put_Msg_in_Folder(const set<Folder*>&);
void remove_Msg_from_Folders();
}; #endif // !MESSAGE_H
#include "stdafx.h"
#include "Message.h" Message::Message(const Message& m):contents(m.contents),folders(m.folders)
{
put_Msg_in_Folder(folders);
} void Message::put_Msg_in_Folder(const set<Folder*>& rhs){
for(set<Folder*>::const_iterator beg = rhs.begin();
beg != rhs.end();++beg)
(*beg)->addMsg(this);
}
Message& Message::operator=(const Message& rhs){
if(&rhs != this){
remove_Msg_from_Folders();
contents = rhs.contents;
folders = rhs.folders;
put_Msg_in_Folder(rhs.folders);
}
return *this;
}
void Message::remove_Msg_from_Folders(){
for(set<Folder*>::const_iterator beg = folders.begin();
beg != folders.end();++beg)
(*beg)->remMsg(this);
} Message::~Message()
{
remove_Msg_from_Folders();
} void Message::addFldr(Folder* f){
folders.insert(f);
} void Message::remFldr(Folder* f){
folders.erase(f);
} void Message::save(Folder& fldr){
addFldr(&fldr);
fldr.addMsg(this);
} void Message::remove(Folder& fldr){
remFldr(&fldr);
fldr.remMsg(this);
} //Folder
Folder::Folder(const Folder& f):messages(f.messages),folder_name(f.folder_name){
put_Fldr_in_Message(f.messages);
} void Folder::put_Fldr_in_Message(const set<Message*>& rhs){
for(set<Message*>::const_iterator beg = rhs.begin();
beg != rhs.end(); ++beg)
(*beg)->addFldr(this);
} void Folder::remove_Fldr_from_Message(){
for (set<Message*>::const_iterator beg =messages.begin();
beg != messages.end(); ++beg)
(*beg)->remFldr(this);
} Folder& Folder::operator=(const Folder& rhs){
if(&rhs != this){
messages = rhs.messages;
folder_name = rhs.folder_name;
put_Fldr_in_Message(messages);
}
return *this;
} Folder::~Folder(){
remove_Fldr_from_Message();
} void Folder::save(Message& msg){
addMsg(&msg);
msg.addFldr(this);
} void Folder::remove(Message& msg){
remMsg(&msg);
msg.remFldr(this);
} void Folder::addMsg(Message* msg){
messages.insert(msg);
} void Folder::remMsg(Message* msg){
messages.erase(msg);
}
C++primer 阅读点滴记录(一)的更多相关文章
- C++primer 阅读点滴记录(三)
14章 操作符重载和转换 重载操作符是具有特殊名称的函数:保留字operator后接需要定义的操作符符号. 1.重载的操作符名: + – * / % ^ & | ~ ! , = < & ...
- C++primer 阅读点滴记录(二)
智能指针(smart point) 除了增加功能外,其行为像普通指针一样. 一般通过使用计数(use count)或引用计数(reference count)实现智能指针,防止出现指针 ...
- C++ Primer 阅读笔记:迭代器和容器 小结
原创 by zoe.zhang 0.写在前面的话 我是在2011年学的C++,但是那一年恰好是C++11新标准的一年,但是大学上学的C++还是基于C++98的风格的,使用的编译器也是VC6.0,啊, ...
- 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介
前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...
- [踏得网]HTML5在线教程阅读进度记录
2017年1月3日18:12:19http://techbrood.com/h5b2a?p=html-canvas-states 2017年1月3日17:10:11http://techbrood.c ...
- android 点滴记录 ICCID IMSI IMEI MEID 关系 和 区别,相关参数在什么情况下可以获取...
1:ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中) ICCID为IC卡的唯一识别号码,共有20位数字组成,其编码格式为:XXXXX ...
- android 点滴记录
1.AndroidM环境下,在framework层添加代码会对jar包的package name进行检查,并提示”unknown package name of class file”怎么解决? 产生 ...
- MiniProfiler使用点滴记录-2017年6月23日11:08:23
1.看似针对同样一段查询表ef达式,重复执行却没有被记录下来.其实这是正常情况,因为ef并没有重复去执行 相同sql查询. 2.MiniProfiler结合MVC过滤器进行 拦截记录Sql,示例代码: ...
- Git点滴记录
合并多个commit记录 假设我们当前有三个commit信息,现在要将commit hash为 23f92c 和 409978 合并 //git rebase -i HEAD~3 那么我们可以使用 r ...
随机推荐
- cocos2d-x 游戏暂停界面,监听home键,返回键,Menu键 解决方案
游戏暂停界面: cocos2d-x中游戏暂停界面提供的思路是用pushScene()和popScne(),即推进和弹出场景,当游戏暂停时,推进(pushScene())暂停场景,之前运行的场景将会自动 ...
- MapReduce从输入文件到Mapper处理之间的过程
1.MapReduce代码入口 FileInputFormat.setInputPaths(job, new Path(input)); //设置MapReduce输入格式 job.waitForCo ...
- Redis附加功能之Redis流水线pipeline
流水线功能的目的:通过减少客户端与服务器之间的通信次数来提高程序的执行效率. 一.通信 在一般情况下, 用户每执行一个 Redis 命令,客户端与服务器都需要进行一次通信:客户端会将命令请求发送给服务 ...
- cocos2d-x 中添加显示文字的三种方式 LabelTTF 、LabelBMFont 和 LabelAtlas
在 cocos2d-x 中有三个类可以在层或精灵中添加文字: LabelTTF LabelBMFont LabelAtlas LabelTTF 直接支持使用 TTF 字库,可以支持全部的中文,但是效率 ...
- Botposter.com集群ETCD2.3.7升级至3.0实录[原创]
7月1日,为庆祝我党生日,ETCD隆重发布了3.0版本.Botposter.com也在第一时间对集群进行了升级.本文是升级过程的记录与总结(文中假设读者已经使用或测试过ETCD V2,如有不妥请见谅) ...
- 设计模式——适配器模式(Adapter Pattern)
解决的问题: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作.比如说我的hp笔记本,美国产品,人家美国的电压是110V的,而我们中国 ...
- 操作系统是怎么工作的——mykernel环境的搭建
可以参见:https://github.com/mengning/mykernel 首先感谢:http://www.euryugasaki.com/archives/1014 1.搭建实验环境(实验环 ...
- dreamweaver cs6 的破解方法
dreamweaver cs6 的破解方法,很简单大家照着下面的方法做肯定能破解方法/步骤 安装DreamWeaver cs6 使用amtlib.dll破解下载amtlib.dll文件后,解压后得到 ...
- Find out who the “mole” is?
Blueheat Company’s production server was out of order again. The CEO was very upset and want their ...
- ntfs安全权限和共享权限的区别
win xp 最大分区32G,最大文件大小4G. 共享权限是为网络用户设置的,NTFS权限是对文件夹设置的. 用户对文件夹有什么权限就是看NTFS权限的设置. 如果一个文件夹设置成共享,其具体的权限还 ...