《Effective C++》 读书笔记之二 构造/析构/赋值运算

简介:

《Effective C++》 读书笔记之二 构造/析构/赋值运算

条款10:令赋值(assignment)操作符返回一个reference to *this。

例子:

1
2
3
4
5
Widget& operator=( const  Widget& rhs)
{
     ...
     return  * this ; //返回*this
}

2016-11-03 09:36:00


条款11:在operator= 中处理“自我赋值”。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class  Widget{
     ...
     void  swap(Widget& rhs); //交换*this与rhs的数据
     ...
};
 
//第一种合理安全的写法
Widget& Widget::operator=( const  Widget& rhs)
{
     BitMap * pOrg = pb;         //记住原先的pb
     pb =  new  BitMap(*rhs.pb);     //令pb指向*pb的一个复件(副本)
     delete  pOrg;                 //删除原先的pb
     return  * this ;
}
//第二种合理安全的写法
Widget& Widget::operator=( const  Widget& rhs)
{
     Widget temp(rhs);
     swap(temp);
     return  * this ;
}

重点:

  1. 确保当对象自我赋值时operator= 有良好行为。其中技术包括比较“来源对象”与“目标对象”的地址、精心周到的语句顺序、以及copy-and-swap。

  2. 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。

2016-11-03 10:23:50


条款12:复制对象时勿忘其每一个成分。Copy all parts of an object.

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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.name)  //复制所有成员,防止局部拷贝(partial copy )
{
     logCall( "Customer copy constructor" );
}
Customer& Customer::operator=( const  Customer& rhs)
{
     logCall( "Customer copy assignment operator" );
     name = rhs.name;
     return  * this ;
}
class  PriorityCustmer:  public  Custmer  //一个derived class
{
public :
     PriorityCustomer( const  PriorityCustomer& rhs);
     PriorityCustomer& operator=( const  PriorityCustomer& rhs);
private :
     int  priority
};
PriorityCustomer::PriorityCustomer( const  PriorityCustomer& rhs)
     :Customer(rhs), //调用base class的copy构造函数,如果不调用,会调用Customer的default构造函数
     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 ;
}

重点:

  1. Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”。

  2. 不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,比如init(),并由两个copying函数共同调用。


本文转自313119992 51CTO博客,原文链接:http://blog.51cto.com/qiaopeng688/1868804
相关文章
|
8月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
331 77
|
6月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
324 6
|
8月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
236 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
8月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
179 12
|
8月前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
130 9
|
8月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
211 7
|
8月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
316 5
|
8月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
185 5
|
11月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
119 1
|
JavaScript Java C语言
面向对象编程(C++篇3)——析构
面向对象编程(C++篇3)——析构
88 2