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的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
随机推荐
- 对ManualResetEvent和AutoResetEvent的巩固练习
在多线程编程中,最常用到的就是线程同步问题,前段时间开发地址采集服务器,需要携带经纬度到MapAbc中采集后,返回地址,才可以进行下一条经纬度的采集,因为队列处理和解析不是同一个线程,并且是解析经纬度 ...
- 从__acrt_first_block == header 谈起,记录dll链接不一致的问题
最近写了一个postgresql的数据库连接池dll.写的比较随意,某个头文件如下: #pragma once #include "common.h"#include " ...
- Bootstrap 4,“未捕获错误:Bootstrap工具提示需要Tether(http://github.hubspot.com/tether/)”
如果出现了这个错误,我想你是没有引用tether文件,这在v4之前不需要单独引入的. https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/te ...
- python捕获异常、处理异常
https://blog.csdn.net/jmilk/article/details/50047457
- mint-ui之picker爬坑记
picker的数据来源为动态获取时,数据无法正常渲染!因为方法不对,所以坑大了!深刻地体会到'业不精,我之过',谨以此文,深刻地记录一下踩坑及爬坑的整个过程,以便日后不再入坑,也给后来者提供一下参考 ...
- tensorflow 1.8, ubuntu 16.04, cuda 9.0, nvidia-390,安装踩坑指南。
被tensorflow 1.8, ubuntu 16.04, cuda 9.0, nvidia-390折磨了5天,终于上坑,留下指南,造福后人. 1.先把依赖搞清楚: tensorflow 1.8依赖 ...
- 16个必须熟悉的linux服务器监控命令
本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc. == 原文:16 Linux Server Monitoring Comman ...
- 关于ConcurrentSkipListMap的理解
一.前言 JCIP 提到了在 Java 6 中引入了两个新的并发集合类 ConcurrentSkipListMap 和 ConcurrentSkipListSet.其实只要介绍一下 Concurren ...
- Tiny4412 烧写uboot到emmc步骤
将uboot写入emmc,并通过EMMC驱动,不在只用SD卡启动 烧写uboot的之前用如下命令查看EMMC卡信息及分区信息: mmcinfo 0: 查看mmc卡信息, 0表示SD卡:1表示emmc卡 ...
- Tiny4412中断之看门狗
一:看门狗(WDT watch dog timer) 看门狗其实是一个计数器,它的作用就是防止程序陷入死循环或者程序运行跑飞:看门狗是一个硬件,它的工作原理是,初始化给他一个值,它会过一段时间减一,直 ...