C++ Primer 5th笔记(chap 13 拷贝控制)拷贝构造函数
1. 拷贝构造函数
如果一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。
class Foo{public:Foo();//默认构造函数 (仅在程序员没有定义构造函数的情况下)Foo(const Foo&);//拷贝构造函数
};
注:拷贝构造函数通常不应该是explicit的, 否则不能用于拷贝形式初始化
Sales_data item1(null_book); // 正确:直接初始化
Sales_data item2 = null_book; //错误:不能将explicit的构造函数用于拷贝形式初始化过程
2、合成拷贝构造函数synthesized copy constructor
如果我们没有给一个类定义拷贝构造函数,则编译器会定义一个拷贝构造函数。
2.1 定义
编译器将其参数的成员逐个拷贝到正在创建的对象中,编译器从给定对象中依次将每个非static成员拷贝到正在创建的对象中。
- 类类型成员:使用它的拷贝构造函数来拷贝
- 内置类型:直接拷贝
- 数组类型:逐元素拷贝
2.2 如果使用的初始化值要求通过一个 explicit 的构造函数来进行类型转换
vector<int> v1(10); //正确,直接初始化
vector<int> v2 = 10; //错误,接受大小参数的构造函数是explicit 的
void f(vector<int>); //f的参数进行拷贝初始化
f(10); //错误,不能使用一个explicit的构造函数拷贝一个实参
f(vector<int>10); //正确,从一个int值直接构造一个临时的vector
3、拷贝初始化
3.1 定义
. 使用指定构造函数创建一个临时对象
. 复制构造函数将那个临时对象复制到正在创建的对象。
3.2 两种初始化
直接初始化: 直接调用与实参匹配的构造函数
拷贝初始化:总是调用复制构造函数
string dots(10,'.'); //直接初始化
string s(dots); //直接初始化
string s2 = dots; //拷贝初始化
string s3 = "9-999-9"; //拷贝初始化
string s4 = string(100,'9'); //拷贝初始化
3.3 注意
. 如果一个类有一个移动构造函数,则拷贝初始化有时会使用移动构造函数而非拷贝构造函数。
. 当复制构造函数被声明为私有时,所有的复制初始化都不能使用。
3.4 拷贝初始化的其他情形:
不仅仅在使用= 定义变量时发生拷贝初始化,如下情况也会发生拷贝初始化:
- 将一个对象作为实参传递给一个非引用类型的形参。
- 从一个返回类型为非引用类型的函数返回对象。
- 用花括号列表初始化一个数组中的元素或者一个聚合类中的成员。
- 某些类类型还会对它们所分配的对象使用拷贝初始化,当初始化标准库容器时,调用其 insert 或 push 成员,容器会对其元素进行拷贝初始化,与之相对,用 emplace 创建的成员执行直接初始化。
4. 编译器可以绕过拷贝构造函数
在拷贝初始化的过程中,编译器可以(但不是必须)跳过拷贝/移动构造函数,直接创建对象。
eg.
string null_book = "9-999-9"; //拷贝初始化
->
string null_book("9-999-9"); //编译器略过了拷贝构造函数
- 前提条件:拷贝/移动构造函数必须是存在并且可访问的
C++ Primer 5th笔记(chap 13 拷贝控制)拷贝构造函数相关推荐
- c++ primer 5th,习题13.3 答案是不是错了?(未解决)
c++ primer 5th,习题13.3 答案是不是错了?如下: 这两个类都未定义拷贝构造函数,因此编译器为它们定义了合成的拷贝构造函数.合成的拷贝构造函数逐个拷贝非 const成员,对内置类型的成 ...
- C++ Primer 5th笔记(chap 13 拷贝控制)合成的移动操作
1. 出现条件 只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个非 static 数据成员都可以移动,编译器才会为它合成构造函数或移动赋值运算符. struc X{int i;std::st ...
- C++ Primer 5th笔记(chap 13 拷贝控制)三五法则
1. 三个基本操作可以控制类的拷贝操作 • 拷贝构造函数 • 拷贝赋值运算符 • 析构函数. 新标准还有2个函数: • 移动构造函数(move constructor) • 移动赋值运算符(move- ...
- C++ Primer 5th笔记(chap 13 拷贝控制)阻止拷贝
对于一些类来说,拷贝操作是没有意义的,例如 iostream 类阻止了拷贝,以避免多个对象写入或读取相同的 IO 缓冲. 1. 删除函数deleted function 1.1 定义 通过在函数的参数 ...
- C++ Primer 5th笔记(chap 13 拷贝控制)=default
可以将拷贝控制成员函数定义为 =default 来显示地要求编译器生成合成版本. class Sales_data{public:Sales_data() = default;Sales_data(c ...
- C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制
1. 虚析构函数 基类通常应该定义一个虚析构函数. class Quote {public:// virtual destructor needed if a base pointer pointin ...
- C++ Primer 5th笔记(chap 18 大型程序工具) 多重继承之构造函数、析构函数
1. 继承的构造函数与多重继承 如果从多个基类中继承了相同的构造函数(即形参列表完全相同),则程序将产生错误 struct Basel {Basel () = default;Basel (const ...
- C++ Primer 5th笔记(chap 18 大型程序工具)noexcept
1. 通过提供 noexcept 说明 ( noexcept specification ) 指定某个函数不会抛出异常. 其形式是关键字 noexcept 紧跟在函数的参数列表后面 {// 紧跟在函数 ...
- C++ Primer 5th笔记(chap 19 特殊工具与技术)union
1. 定义 联合( union) 是一种特殊的类. 一个 union 可以有多个数据成员, 但是在任意时刻的某个成员赋值之后, 该 union 的其他成员就变成未定义的状态了. 对象的存储空间至少要能 ...
- C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化
1. 定义一个特例化版本, 模板参数为 Sales data // 打开std 命名空间, 以便特例化 std::hash namespace std {template struct hash< ...
最新文章
- 几种常用 JSON 库性能比较
- 聊天机器人之需求分析和流程介绍
- 吸墨网iPhone手机客户端界面设计
- 《笑谈银行IT》—畅谈“银行IT系统”
- 通信网络基础期末复习-第五章-路由算法
- 微信公众号开发 回复事件(测试账号)
- [转载]常用CASE工具介绍
- 关于oracle sql语句查询时表名和字段名要加双引号的问题
- UVA - 1339 ​​​​​​​Ancient Cipher
- codesys com库_CODESYS在线库,酷德网镜像站启用
- 帆软报表如何传递主表原有参数给子表呢_报表工具--钻取功能--超链接下钻
- 拍摄女生人像,摄影师觉得最大的困难是什么?
- script标签async和defer的区别及作用
- 下载美国气候数据中心地址
- 包干到户是最好的软件项目管理方法
- Envoy proxy 源代码解读 - original_dst cluster
- DNS解析与域名服务安全防护策略
- Excel:一维表和二维表 互转
- 大学本科毕业生如何免费进行论文查重
- mpos判断条件由接口返回
热门文章
- java强制编译通过_强制java使用用户输入作为消息进行编译错误
- 做弱电机房工程的时候,如何解决机房称重问题?
- 向数据中心劳动者致敬!
- linux文件拷贝函数,linux:文件操作函数(open,close,read,write)
- 机器人鸣人是哪一集_火影里的五个机器人,第一个比鸣人还厉害,机器丁次你都没见过...
- 8分频verilog线_Verilog设计分频器(面试必看)
- excel制作录入和查询系统_excel表格制作成绩查询系统攻略:让学生隐私更安全!
- php源代码压缩,PHP_PHP 源代码压缩小工具,使用方法:(在命令行运行) 复 - phpStudy...
- python:程序猿的方式在元宵佳节之际,带你设计【东方明珠】动画浪漫烟花秀(python编程利用Tkinter+PIL库)
- ML之Kmeans:利用自定义Kmeans函数实现对多个坐标点(自定义四个点)进行自动(最多迭代10次)分类