P406 复制控制

不管类是否定义了自己的析构函数,编译器都自动执行类中非static数据成员的析构函数。

复制构造函数

C++支持两种初始化形式:直接初始化和复制初始化。
复制初始化使用=符号,直接初始化将初始化式放在圆括号中。

当初始化用于类类型时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定的构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到正在创建的对象。

以非引用类型作返回值时,将返回return语句中的值的副本。
当形参或返回值为类类型时,由复制构造函数进行复制。

合成的复制构造函数的行为是:执行逐个成员初始化(即编译器将现有对象的每个非static成员,依次复制到正创建的对象)。合成复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制。

禁止复制 P410

有些类需要完全禁止复制,比如iostream类。如果想要禁止复制,似乎可以省略复制构造函数,然而,如果不定义复制构造函数,编译器将合成一个。
为了防止复制,类必须显式声明其复制构造函数为private。但这样,类的友元和成员仍可以进行复制。如果想连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义。声明而不定义成员函数是合法的,但是,使用未定义成员的任何尝试将导致链接失败。

析构函数 P413

构造函数与复制构造函数或赋值操作符之间的一个重要区别是,即使我们编写了自己的析构函数,合成析构函数仍然运行。

撤销一个容器(不过是标准库容器还是数组)时,也会运行容器中的类类型元素的析构函数。

{Sales_item *p = new Sales_item[10];vector<Sales_item> vec(p, p+10);delete [] p;  // array is freed, destructor run on each element
} // vector goes out of scope; destructor run on each element
复制代码

容器中的元素总是按逆序撤销:首先撤销下标为size()-1的元素,最后是下标为0的元素。

合成析构函数按照对象创建时的逆序撤销每个非static成员,因此,它按照成员在类中声明次序的逆序撤销成员。对于类类型的每个成员,合成析构函数调用该成员的析构函数来撤销对象。

重载赋值操作符 operator=

将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数;之所以少一个参数,是因为这个参数是隐含的*this;如:

// 假设 complex 类中重载了加法运算符:
complex& operator+(const complex & A);// c1 c2 c3都是类对象
c3 = c1 + c2;// 会被转换为:
c3 = c1.operator+(c2); // 通过 this 指针隐式的访问 c1 的成员变量。
复制代码

将运算符重载函数作为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质; 如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C++内置类型的数据;如:

// 例如,下面这样是不对的:
int operator + (int a,int b){return (a-b);
}
// +号原来是对两个数相加,现在企图通过重载使它的作用改为两个数相减, 如果允许这样重载的话,
// 那么表达式4+3的结果是 7 还是 1 呢?显然,这是绝对禁止的。// 如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C ++内置类型的数据,例如:
complex operator+(int a, complex &c)
{return complex(a+c.real, c.imag);
}
// 它的作用是使一个整数和一个复数相加。
复制代码

c++ primer 笔记[20190406]相关推荐

  1. C++Primer笔记——拷贝控制

    CHAPTER13-拷贝控制(C++ Primer笔记) 13.1 拷贝.赋值与销毁 13.1.1 拷贝构造函数 13.1.2 拷贝赋值运算符 13.1.3 析构函数 13.1.4 三/五法则 13. ...

  2. c++ primer 笔记 (二)

    第二章笔记  (貌似记得有点多)   把负值赋给unsigned对象时完全合法的,其结果是该负数对该类型的取值个数求模后的值   -1     (对265求模)  255 float型只能保证6位有效 ...

  3. C++Primer笔记-A003-decltype使用

    导言 此次笔记分为三部分介绍 typedef 基本使用与cpp11新特性 自动推演数据类型 decltype使用(主要集中介绍) typedef typedef使用方法很简单,就是为一个数据类型取一个 ...

  4. C++ Primer笔记——顶层const和底层const区别

    顶层const和底层const的区别 书中的定义: 顶层const(top-level const):表示指针本身是个常量. 底层const(low-level const):表示指针所指的对象是一个 ...

  5. Primer笔记——typedef指针类型别名时的const陷阱

    目录 一.typedef int* pint 与 const pint 二.typedef const int *pint 与 pint 三.总结 <C++ Primer>中指出,type ...

  6. C++primer笔记之关联容器

    在这一章中,有以下的几点收获: 1.pair类型的使用相当频繁,如果需要定义多个相同的pair类型对象,可考虑利用typedef简化其声明: typedef pair<string, strin ...

  7. C++ Primer笔记12_运算符重载_递增递减运算符_成员訪问运算符

    1.递增递减运算符 C++语言并不要求递增递减运算符必须是类的成员.可是由于他们改变的正好是所操作对象的状态.所以建议设定为成员函数. 对于递增与递减运算符来说,有前置与后置两个版本号,因此.我们应该 ...

  8. C++ primer 笔记 (一)

    C++基本要素: 内置类型.库类型.类类型.变量.表达式.语句和函数 main函数是代码的入口,其返回值必须是int 类型(有时为void),其返回值是一个状态指示器,返回值为0,则表示函数成功执行完 ...

  9. C++Primer笔记-----day04

    1.函数指针. 函数指针指向某种特定类型,函数的类型由它的返回类型和形参类型决定,与函数名无关. 比如:bool lengthCompare(const string &,const stri ...

最新文章

  1. ISO9000管理体系认证申请书
  2. 简易mysql优化_优化 MySQL:简单三个技巧
  3. linux命令查看g 版本,如何查看linux版本
  4. git fatal:HttpRequestException encountered
  5. 学习微软企业库的心得-验证
  6. 开放接口加密方案_27种开放式解决方案,适用于所有教育
  7. ES2018 学习笔记(4)Unicode 和 ISO 10646
  8. WPF管理系统自定义分页控件 - WPF特工队内部资料
  9. 网易新闻iOS版开发使用的第三方框架和组件列表
  10. 以德服人——合格的产品经理
  11. 快速上手OSS图片视频上传
  12. 产品目标拆解:结构化思维
  13. C语言入门递归算法——汉诺塔(简单易懂,最后还有汉诺塔游戏)
  14. 制作一个简单的倒计时动画
  15. Pandas官方文档!(中文版PDF下载)
  16. unity 3D物体添加 点击事件
  17. 虚拟机启动时,提示找不到ISO映像文件
  18. PHP通过HTTP_USER_AGENT判断是否为手机移动终端的函数
  19. 修改数据库表字段长度
  20. (九)数字后端之静态时序分析STA

热门文章

  1. 怎么查看这个历史最大连接session数
  2. “安全即代码”:整合安全团队和DevOps团队
  3. 浅尝key-value数据库(三)——MongoDB的分布式
  4. Linq之延迟加载特性
  5. GdiPlus[6]: 五种画刷总览
  6. Linux下磁盘读写优化的分析
  7. 【C++基础学习】C++中的引用
  8. 小shell脚本---查找目录下面包含string的文件
  9. linux终端程序如何编写,[LINUX]利用Ncursesw编写支持中文的终端程序
  10. php播放音乐视频,html5停止(暂停)当前播放的音频或视频的方法pause()