EffectiveC++ 第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
EffectiveC++ 第2章 构造/析构/赋值运算的更多相关文章
- 《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- 《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- Effective C++ —— 构造/析构/赋值运算(二)
条款05 : 了解C++默默编写并调用哪些函数 编译器可以暗自为class创建default构造函数.copy构造函数.copy assignment操作符,以及析构函数. 1. default构造函 ...
- Effective C++ 笔记二 构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inlin ...
- Effective C++笔记:构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- Effective C++ -- 构造析构赋值运算
05.了解C++默默编写并调用哪些函数 编译产生的析构函数时non-virtual,除非这个类的基类析构函数为virtual 成员变量中有引用和const成员时,无法自己主动生成copy assign ...
- Effective C++笔记(二):构造/析构/赋值运算
参考:http://www.cnblogs.com/ronny/p/3740926.html 条款05:了解C++默默编写并调用哪些函数 如果自定义一个空类的话,会自动生成默认构造函数.拷贝构造函数. ...
- 【Effective C++】构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- Effective C++ 2.构造 析构 赋值运算
//条款07:为多态基类声明virtual析构函数 // 1.若基类的析构函数不定义为虚函数,由于基类的指针或引用可以指向派生类的对象,则在删除基类对象的时候可能会出错,导致破坏数据结构. // 2. ...
随机推荐
- springboot项目
https://my.oschina.net/ityouknow/blog/1629066
- Vue项目中的RSA加解密
前后端使用rsa加密: 一般是客户端初始化时访问登录服务时,服务端面动态生成一对RSA对,公钥传给客户端,客户端拿到后,用户输入密码后,点登录时用公钥加密返回给服务端,服务端用私钥解就行了 一.安装 ...
- Linux操作系统上要慎用的6个命令及防范方法
Linux操作系统上要慎用的6个命令及防范方法 基于Linux平台工作的童鞋都知道Linux命令行使用起来非常高效和快捷,但有时候也很危险,尤其是在你不确定你自己在正在做什么时候(别笑,别以为自己真的 ...
- MySQL之表相关操作
一 存储引擎介绍 存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制 详见:http://www.cnblogs.com/linhaifeng/articles/7213670.html ...
- Mango 基础知识
1 mongdb和python交互的模块 pymongo 提供了mongdb和python交互的所有方法 安装方式: pip install pymongo 2 使用pymongo 1. 导入pymo ...
- 初学python必备基础知识
一,编程语言介绍 1.机器语言:直接用二进制编程,直接控制硬件,需要掌握硬件的操作细节 优点:执行效率高 缺点: 开发效率低 2.汇编语言:用英文标签取代二进制指令去编写程序,直接控制硬件,需 ...
- SQL分组求每组最大值问题的解决方法收集 (转载)
例如有一个表student,其结构如下: id name sort score 1 张三 语文 82 2 李四 数 ...
- MongoDB小东西
在mongodb中,show users 和db.system.users.find() 都能查看账户的相关信息,但是这两个命令有什么区别么? db.system.users.find() 是查看全局 ...
- 《构建之法》课程进度之Github、Travis等工具融入篇
<构建之法>里有一个16周的软件工程课程进度设计.本文在该基本设计的基础上,围绕github.com(源码管理).travis-ci.org(持续集成).单元测试工具.日志工具.少数实用U ...
- vue中使用Base64和md5和rsa
https://blog.csdn.net/benben513624/article/details/88113459(copy) https://www.cnblogs.com/myfate/p/1 ...