Item 5: Know what functions C++ silently writes and calls

在C++中,编译器会自己主动生成一些你没有显式定义的函数,它们包含:构造函数、析构函数、复制构造函数、=运算符。
有时为了符合既有设计。我们不希望自己主动生成这些函数。我们能够把它们显式声明为private
此时在使用这些类的客户看来,它们就像不存在一样。

class Empty{
public:
// 默认构造函数
Empty(){}
// 拷贝构造函数
Empty(const Empty& rhs){}
// 析构函数
~Empty(){}
// 赋值运算符
Empty& operator=(const Empty& rhs){}
};

这些编译器自己主动生成的缺省方法是能够禁用的,把它们声明为private便能解决绝大多数问题。
很多其它的讨论能够參考:Item 6: 禁用那些不须要的缺省方法-Effective
C++笔记

调用时机

当我们没有显式地定义上述这四种函数时。编译器会自己主动帮我们定义。

这些函数它们调用的时机例如以下:

  1. 构造函数:对象定义;使用其它兼容的类型初始化对象时(可使用 explicit 来避免这样的情况)
  2. 复制构造函数:用一个对象来初始化还有一对象时。传入对象參数时。返回对象时。
  3. 析构函数:作用域结束(包含函数返回)时。delete
  4. =运算符:一个对象赋值给还有一对象

为了更清晰地说明它们的调用时机。来个样例吧:

Empty e1;               // 默认构造函数
Empty e2(e1); // 拷贝构造函数
Empty e3 = e1; // 拷贝构造函数
e2 = e1; // = 运算符 void func(Empty e){ // 拷贝构造函数。拷贝一份參数对象
return e; // 拷贝构造函数。拷贝一份返回对象
// 析构函数。拷贝得到的參数对象被析构
} e2 = func(e1); // = 运算符
// 析构函数。返回值被析构

引用成员

当对象包括引用成员时,拷贝和赋值行为将会变得很有趣,考虑这样一个类:

class Person{
public:
string & name;
Person(string& str): name(str){ }
};
string s1 = "alice", s2 = "bob";
Person p1(s1), p2(s2); s1 = s2;

赋值后,p1.name会指向p2.name吗?我们知道在C++中引用本身是不可改动的。

即使p1.name指向了p2.name。那么对p1.name的赋值将会影响到p2
于是。C++拒绝编译上述代码,此时我们须要手动定义一个赋值运算符。

说来奇妙。拷贝构造函数也存在相同的问题,编译器却从不抱怨。

能够正常编译,而且两个引用指向同一对象。


除非注明,本博客文章均为原创。转载请以链接形式标明本文地址: http://harttle.com/2015/07/23/effective-cpp-5.html

Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记的更多相关文章

  1. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  2. Effective C++(5) 了解C++默默地编写并调用哪些函数

    预热: 一个空的类,当编译器处理过之后,就包含: 一个copy构造函数 一个重载赋值操作符 一个析构函数 一个默认构造函数 Demo: class Empty() { }; // 声明一个空的类 cl ...

  3. Effective C++ 之 Item 5:了解C++默默编写并调用哪些函数

    Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 5 ...

  4. item 5: 比起显式的类型声明,更偏爱auto

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 啊,简单愉快的代码: int x; 等等,讨厌!我忘了初始化x,所 ...

  5. Effective C++ 之 Item 6 : 若不想使用编译器自动生成的函数,就该明确拒绝

    Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 6 ...

  6. 读书笔记 effective c++ Item 36 永远不要重新定义继承而来的非虚函数

    1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void. ...

  7. C#中声明、调用和配置事件的演示源码

    下面的内容是关于C#中声明.调用和配置事件的演示的内容,应该能对大伙有些好处. using System;namespace MyCollections { using System.Collecti ...

  8. Effective STL 笔记 -- Item 6 ~ 7: Container and Object Pointer

    Effective STL 笔记 – Item 6 ~ 7: Container and Object Pointer 中间两次笔记被删掉了,简单补一下: Item 3 中提到如果将对象直接放入容器中 ...

  9. EC笔记,第二部分:5.了解C++默默编写并调用哪些函数

    5.了解C++默默编写并调用哪些函数 1.C++空类 C++会为一个空类建立以下函数 (1).默认构造函数 (2).默认拷贝构造函数 (3).析构函数 (4).赋值运算符(如果成员包含引用类型或con ...

随机推荐

  1. sql server 存储过程解密

    Create PROCEDURE [dbo].[sp_windbi$decrypt] () AS /**//* 王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com 调用形式为: ...

  2. 安装 jupyter notebook 出现 ModuleNotFoundError: No module named 'markupsafe._compat' 错误

    使用 python -m pip install jupyter 安装完成 jupyter notebook 之后,在命令行界面输入 "jupyter notebook "指令打开 ...

  3. Codeforces Round #302 (Div. 1) D - Road Improvement 树形dp

    D - Road Improvemen 思路:0没有逆元!!!! 不能直接除,要求前缀积和后缀积!!! #include<bits/stdc++.h> #define LL long lo ...

  4. CSS3之背景定位原点background-origin

    背景定位原点background-origin是CSS3新添加的有关背景的属性,主要是改变背景起始的原点位置的.CSS3之背景定位原点background-origin的属性值有三个:border.p ...

  5. openwrt 控制gpio口的方法

    利用i2c来控制gpio口 1.编译驱动或者安装驱动 # opkg update # opkg install kmod-i2c-gpio-custom kmod-i2c-core# 加载驱动 # i ...

  6. MAC OS 10.11.1虚拟机免费下载已安装Xcode7图片后有下载地址

    MAC OS 10.11.1虚拟机免费下载已安装Xcode7图片后有下载地址 注意:已经下载过MAC OS 10.10.5虚拟机免费下载(可安装Xcode7)链接:http://www.cnblogs ...

  7. 初探 Spring Boot

    近些年Spring Boot都特别火,一直都想来学习学习,奈何近期公司项目繁忙,一直都没有时间来学习,今天终于是休息一天,于是来一睹 SpringBoot 的风采. 一.什么是Spring Boot ...

  8. 【BZOJ 2957】 2957: 楼房重建 (线段树)

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1753  Solved: 841 Description 小A的楼房外有一大片施 ...

  9. 51nod1515 明辨是非 并查集 + set

    一开始想的时候,好像两个并查集就可以做......然后突然懂了什么.... 相同的并查集没有问题,不同的就不能并查集了,暴力的来个set就行了..... 合并的时候启发式合并即可做到$O(n \log ...

  10. Failed to read auto-increment value from storage engine错误的处理方法

    在进行数据的插入时,系统提示Failed to read auto-increment value from storage engine(从存储引擎读取自增字段失败)错误,经查阅资料,解决方法如下: ...