EffictiveC++笔记 第2章
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的“可能比较准确”的「翻译」。
Chapter 2 构造 / 析构 / 赋值
条款 05:了解C++ 默默编写并调用哪些函数
如果你写下:
class Empty{ };
事实上编译器会帮你补全:
class Empty{
public:
Empty() { }
Empty(const Empty& rhs) { }
~Empty() { }
Empty& operator=(const Empty& rhs) { }
} ;
这些函数只有被需要时才会被创建出来
默认构造函数只是单纯的将来源对象每个non-static成员变量拷贝到目标对象
条款 06: 若不想使用编译器自动生成的函数,就改明确拒绝
将拷贝构造函数和赋值重载函数显式声明为private吧
但有一个小缺陷,就是member函数和友元函数依然可以访问,但是会造成连接错误(linkage error)
编译的话连接器会报错
条款07: 为多态基类声明 virtual析构函数
不作为基类的类不要声明虚析构函数
有继承关系的基类一定加上virtual析构函数(带多态性质的base class)
pure virtual纯虚构函数: virtual ~XXX() = 0;
条款 08: 别让异常逃离析构函数
如果客户需要对某个函数运行期间抛出的异常作出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作
条款 09: 绝不在构造和析构过程中调用virtual 函数
若是有两个有继承关系的类,主类有一个virtual函数,并在构造函数里调用;子类定义了另一个版本的此函数,当在main里构造此子类对象时,实际上还是先调用基类的构造函数,然而基类构造函数调用的virtual
函数版本实际上还是基类的。若此函数会使用子类里的元素,然而之类成员都还未初始化,就会引发错误
当类中有多个构造函数,它们兴许有共同的部分。有一种较为出色的做法是定义一个void类型的init函数,然后将初始化中需要调用的函数放在里面,将init单独放在构造函数里就好了。
综上,在构造和析构期间不要调用虚函数,因为这类调用从不下降至derived class
条款 10: 令 operator= 返回一个 reference to *this
int x,y,z;
x = y = z = 15;
根据右结合律,可以解释为x = (y = (z = 15));
为了实现连锁赋值,赋值操作赋必须返回一个reference指向操作符左侧实参:
class Widget{
public:
…
Widget& operator=(const Widget& rhs){
…
return *this;
}
};
此标准适用于所有与赋值相关运算
条款 11:在 operator=中处理自我赋值
类对象的赋值,看下面一种情况:
class Widget{
…
private:
Bitmap* pb;
};
Widget& Widget::operator=(const Widget& rhs)
{
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
存在的问题是,如果*this和rhs是同一个对象,delete操作会同时删除两者的bitmap。可以这样操作:
Widget& Widget::operator=(const Widget& rhs)
{
if(this==&rhs) return *this; //如果是自我赋值则不做任何事
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
条款 12: 复制对象时勿忘其每一个成分
如果对于拷贝函数,你的复制成员没有写全,编译器是不会报错的,因为这符合逻辑。所以记得将需要拷贝的成员变量都放进copying函数
另外,当手动撰写继承类的copying函数时,一定记得在初始化列表复制其base class的成分.否则在复制构造函数中base class成分会由base class的default构造函数初始化,而copy assignment函数根本不会管base class的成分
可以这样写:(A extends B)
在copy函数中:
A::A(const A& rhs):B(rhs)
{
……
}
在copy assignment函数中:
A& A::operator=(const A& rhs)
{
if(this==&rhs)
return *this;
B::operator=(rhs); //对base class成分进行赋值动作
……
return *this;
}
现在很清楚了,当你编写一个copying函数,请确保(1)复制所有local成员变量(2)调用所有base classes内适当的copying函数
OVER
EffictiveC++笔记 第2章的更多相关文章
- EffictiveC++笔记 第1章
Chapter 一: 条款 1 :视 C++为一个语言联邦 (P41 ) c++其实可以视为有四个部分: C Object-Oriented C++ Template C++ STL 条款 2:尽量以 ...
- EffictiveC++笔记 第3章
Chapter 3 资源管理 条款13: 以对象管理资源 有时即使你顺利地写了对应对象的delete语句,但是前面的区域可能会有一个过早的return语句或者抛出了异常.它们一旦执行,控制流绝不会触及 ...
- Stealth视频教程学习笔记(第二章)
Stealth视频教程学习笔记(第二章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- Stealth视频教程学习笔记(第一章)
Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试
20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...
- java JDK8 学习笔记——第16章 整合数据库
第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...
- CSS3秘笈第三版涵盖HTML5学习笔记1~5章
第一部分----CSS基础知识 第1章,CSS需要的HTML HTML越简单,对搜索引擎越友好 div是块级元素,span是行内元素 <section>标签包含一组相关的内容,就像一本书中 ...
- Android群英传笔记——第七章:Android动画机制和使用技巧
Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中 ...
- Android群英传笔记——第六章:Android绘图机制与处理技巧
Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
随机推荐
- 通过slave_exec_mode=IDEMPOTENT跳过主从复制中的错误
通过slave_exec_mode=IDEMPOTENT跳过主从复制中的错误 set global slave_exec_mode=IDEMPOTENT slave_exec_mode 有两种模式 S ...
- Play Framework, Server Sent Events and Internet Explorer
http://www.tuicool.com/articles/7jmE7r Next week I will be presenting at Scala Days . In my talk I w ...
- 0基础一分钟入门Python
这篇文章面向所有想学python的小伙伴(甚至你从没听过编程),这篇文章将会带你以最快的速度入门python.赶快上车,时间来不及了... 一,下载和安装python 1.下载: 1.1 python ...
- Codeforces 623D [Amazing概率题]
很有趣的一道题吖! 做法:贪心+迭代 Sigma(i*(pr[i]-pr[i-1])))=n-sigma(pr[i]), 所以我们贪心地是pr[i]尽可能大. 也就是让pr[i]/pr[i-1]尽可能 ...
- 如何在python脚本开发做code review
在软件项目开发中,我们经常提到一个词“code review”.code review中文翻译过来就是代码评审或复查,简而言之就是编码完成后由其他人通过阅读代码来检查代码的质量(可编译.可运行.可读. ...
- [Python学习之路] 猜大小游戏
# coding =utf-8 import random def roll_dice(number=3, points=None): if points == None: points = [] w ...
- python之字典、列表、元组生成器的使用
python的生成式在一些类型相互转换的时候可以写出十分优雅的代码.如列表转换成另一个列表.字典.或元组.并且代码的执行效率也比使用for...in...循环高. 列表生成式 列表生成式即生成列表的生 ...
- WPF MVVM UI分离之《交互与数据分离》
在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下面的问题: 删除操作,假如需要先执行一部分数据的处理,然后删除界 ...
- Linux kernel的中断子系统之(八):softirq
返回目录:<ARM-Linux中断系统>. 总结:中断分为上半部和下半部,上半部关中断:下半部开中断,处理可以延迟的事情.下半部有workqueue/softirq/tasklet三种方式 ...
- CKEditor、UBB编辑器的使用总结
2018-04-08 22:07:16.188 ERROR 14728 --- [nio-8082-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Se ...