Effective C++ 条款12:复制对象时勿忘其每一个成分
void logCall(const std::string& funcName);
class Customer {
public:
...
Customer (const Customer& rhs);
Customer& operator=(const Customer& rhs);
...
private:
std::string name;
};
Customer::Customer(const Customer& rhs) : name(rhs.anme) {
logCall("Customer copy constructor");
}
Customer& Customer::operator=(const Customer& rhs) {
logCall("Customer copy assignment operator");
name = rhs.name;
return *this;
}
以上看起来并没有任何问题,但是我们为它添加一个成员变量
class Date { ... };
class Customer {
public:
...
private:
std::string name;
Date lastTransaction;
}
我们添加了一个成员变量,如果我们在copying函数中没有对其进行赋值,编译器也不会报错,这个时候可能不是我们想要的结果。
class PriorityCustomer: public Customer {
public:
...
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
...
private:
int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs):priority(rhs.priority) {
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs) {
logCall("PriorityCustomer copy assignment operator");
priority = rhs.priority;
return *this;
}
PriorityCustomer继承了Customer,而那些成员变量却未被赋值。但在构造PriorityCustomer之前,肯定调用了Customer构造函数(即default构造函数——必定有一个否则无法通过编译)初始化。default构造函数将指针对name和lastTransaction执行缺省的初始化动作。
任何时候只要你承担起"为derived class 撰写copying函数"的重大责任,必须很小心地也复制其base class成分。那些成分往往是private,所以你无法直接访问它们,你应该让derived class的copying函数调用相应的base class函数:
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs) : Customer(rhs),priority(rhs.priority) {
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs) {
logCall("PriorityCustomer copy assignment operator");
Customer::operator(rhs); // 对base class成分进行赋值动作
priority = rhs.priority;
return *this;
}
copy assignment和copy构造函数可能存在相同的代码,但是它们两者之间任何一个调用另外一个都是不合法的。
总结
- Copying函数应该确保复制”对象内的所有成员变量”及”所有base class成分”。
- 不要尝试以某个copying函数实现另外一个copying函数。应将共同机能放进第三个函数中,并有两个copying函数共同调用。
Effective C++ 条款12:复制对象时勿忘其每一个成分的更多相关文章
- Effective C++ -----条款12: 复制对象时勿忘其每一个成分
Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...
- EC读书笔记系列之7:条款12 复制对象时勿忘其每一个成分
记住: ★copying函数应确保复制“对象内的所有成员变量”及“所有base class成分” ★不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两 ...
- Effective C++_笔记_条款12_复制对象时勿忘其每一个成分
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...
- EC笔记:第二部分:12、复制对象时勿忘其每一个成分
EC笔记:第二部分:12.复制对象时勿忘其每一个成分 1.场景 某些时候,我们不想使用编译器提供的默认拷贝函数(包括拷贝构造函数和赋值运算符),考虑以下类定义: 代码1: class Point{ p ...
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
NOTE: 1.Copying 函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 2.不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个 ...
- [Effective C++ --012]复制对象时勿忘其每一个成分
引言: 在深拷贝和浅拷贝的理解中,我们知道了“拷贝构造函数”一词,并且也了解了它的构成. A(const A& r); // 形式有多种,在这里只列出一个 因此,在值传递的应用场景里,我们可以 ...
- C++复制对象时勿忘每一部分
现看这样一个程序: void logCall(const string& funcname) //标记记录 { cout <<funcname <<endl; } cl ...
- Effective C++(12) 复制对象时要复制每一个成员
问题聚焦: 负责拷贝的两个操作:拷贝构造函数和重载赋值操作符. 一句话总结,确保被拷贝对象的所有成员变量都做一份拷贝. Demo void logCall(const std::string&am ...
- Effective C++ 条款12
复制对象时,勿忘其每个成分 作者在本节条款提醒我们,在多重继承的情况下进行copy或者copy assignment 的operator=的编写时,一定要考虑base 类部分数据的初始化后者复制. 对 ...
随机推荐
- Import error: no module named cv2 错误解决方法
Windows: 将opencv安装目录下的cv2.pyd拷贝到Python安装目录里Lib中site-packages Linux: (1)将opencv安装目录下的cv2.so拷贝到Python安 ...
- Kotlin——高级篇(二):高阶函数详解与标准的高阶函数使用
在上面一个章节中,详细的讲解了Kotlin中关于Lambda表达式的语法以及运用,如果还您对其还不甚理解,请参见Kotlin--高级篇(一):Lambda表达式详解.在这篇文章中,多次提到了Kotli ...
- 妈妈再也不用担心我使用git了
妈妈再也不用担心我使用git了 Dec 29, 2014 git git由于其灵活,速度快,离线工作等特点而倍受青睐,下面一步步来总结下git的基本命令和常用操作. 安装msysgit 下载地址:ms ...
- 全局安装了express框架,但是无法使用express指令的问题
错误截图: 产生这个错误的原因是:我安装的是express4版本,需要安装express-generator才能使用express命令 将express-generator安装后就都解决了:
- Quest Active Directory
Get-QADGroupMember命令是Quest Active Directory的命令,必须安装如下包才能使用! 电脑路径: D:\soft\AD\Quest_Quest-One-ActiveR ...
- python基础之类的进阶
一.__setitem__,__getitem,__delitem__ #把对象操作属性模拟成字典的格式 class Foo: def __init__(self,name): self.name=n ...
- IIS设置文件 App_Offline.htm 网站维护
在ASP.NET 2.0 站点根目录下,只要存在 App_Offline.htm 文件,那么所有对.aspx的请求都将转向App_Offline.htm .而且浏览器的地址栏显示的是所请求的.aspx ...
- C#中的另类语法
一..net中return的另类写法: 不知道是从3.5还是从4.0开始C#语法中的return有了新的写法示例如下: public string functionDemo() { str ...
- gevent For the Working Python Developer
Gevent指南 gevent程序员指南 由Gevent社区编写 gevent是一个基于libev的并发库.它为各种并发和网络相关的任务提供了整洁的API. 介绍 贡献者 核心部分 Greenle ...
- 我的Android进阶之旅------>解决Error:Could not find property 'compile' on org.gradle.api.internal.artifacts.
1错误描述 解决方法 1错误原因 2解决方法 1.错误描述 刚刚,Android Studio突然编译不了了,报了如下错误: Error:Could not find property 'compil ...