CppPrimer笔记 Chapter13 拷贝控制
来源:互联网 发布:手机磁力链接播放软件 编辑:程序博客网 时间:2024/05/22 17:28
CppPrimer笔记 Chapter13 拷贝控制
标签: Cpp
- CppPrimer笔记 Chapter13 拷贝控制
- 概述
- 拷贝赋值与销毁131
- 拷贝控制和资源管理132
- 动态内存管理类135
- 对象移动136
概述
一个类通过定义五中特殊成员函数来控制对象的:
拷贝 移动 赋值 销毁
包括
拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符 析构函数
拷贝,赋值与销毁(13.1)
- 若一个构造函数的第一个参数是自身类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数.
- 第一个参数必须为引用,通常为const.函数一般不应是
explicit
- 即使我们定义了自己的拷贝构造函数,编译器仍会合成拷贝构造函数.(不同于构造函数)
- 赋值运算符通常应返回指向左侧运算对象的引用
- 析构函数为
~className();
,不能重载,一类唯一. - 成员按初始化顺序逆序销毁(销毁是隐式的,发生在函数体后)
- 隐式销毁一个内置指针类型的成员不会delete对象,那么一个对象的指针或引用离开作用域时,析构函数不会执行.
- 对于一个需要自定义析构函数的类,一般需要自定义的拷贝与赋值操作
- 定义删除的函数来阻止默认生成的拷贝与赋值默认函数
NoCopy(const NoCopy&) = delete;//阻止拷贝
//阻止赋值
NoCopy &operator=(const NoCopy&) = delete; - 析构函数不能是删除成员
- 当不可能拷贝,赋值或销毁类的成员时,类的合成拷贝控制成员就被定义为删除的(P450,P476,P553,P751)
拷贝控制和资源管理(13.2)
- 对赋值运算符来说,一个好的方法是在销毁左侧运算对象资源之前拷贝右侧运算对象.否则如下,当rhs与本对象为同一个对象时,
delete ps
会释放*this和rhs指向的string
HasPtr& HasPtr::operator= (const HasPtr &rhs){ delete ps; ps = new string(*(rhs.ps)); i = rhs.i; return *this;}
动态内存管理类(13.5)
- 在新内存中构造
string
等对象时,需调用move
,否则会使用string
的拷贝构造函数 - 我们通常不为
move
提供一个using
声明,而直接使用std::move()
对象移动(13.6)
- 标准库容器,string,与shared_ptr类支持移动与拷贝,IO与unique_ptr可以移动但不能拷贝
- 左值与右值绑定
int i = 42; int &r = i;//ok int &&rr = i;//error:右值引用不能绑定到左值上 int &r2 = i * 42;//error:i*42是右值 const int &r3 = i * 42;//ok 可以将一个const的引用绑定到一个右值上 int &&rr2 = i * 42;//ok int &&rr1 = 42;//ok,字面常量是右值 int &&rr3 = rr1;//错误,表达式rr1是左值
- 利用
int &&rr3 = std::move(rr1);
来获得绑定到左值上的右值引用.意味着:除了对rr1赋值或销毁它外,我们将不再使用它.
即:可以销毁一个移后源对象(rr1),也可以赋予它新值,但不能使用一个移后源对象 - 移动操作后,移后源对象必须保持有效,可析构状态,但用户不能对其值进行任何假设.
- 当一个类没有定义任何自己版本的拷贝控制成员,且其所有数据成员都能移动构造或移动赋值时,编译器才会为它合成上述两个函数.否则,会是删除的
- 函数的返回值
StrVec getVec(){StrVec x; return x;} StrVec v1,v2; v1 = v2; v2 = getVec();
若StrVec
定义了移动拷贝构造与赋值函数,那么会在getVec()
的return
时
1. 调用移动构造函数,创建一个新的对象(临时对象,右值)2. 析构函数内的局部变量3. 调用移动赋值函数,将创建的右值移动给`v2`4. 调用析构函数,析构创建的临时对象
若StrVec
未定义了移动拷贝构造与赋值函数,那么会在getVec()
的return
时
1. 调用拷贝构造函数,创建一个新对象(临时)2. 析构函数内部的局部变量3. 调用拷贝赋值函数,将创建的右值拷贝给`v2`4. 调用析构函数,析构创建的临时对象
- 若类有可用的拷贝构造函数而没有移动构造函数,而其对象是通过拷贝构造函数来”移动”的
uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),first);
construct使用移动构造函数来构造元素
- 区分移动和拷贝的重载函数通常是两个版本 一个
const T&
一个T&&
- 利用
&
与&&
像const
一样置于函数参数列表后(引用限定符),限定返回值是左值还是右值,避免s1+s2="word"
这样的语句
注意,同const一样,在声明与定义时均需加上
引用限定符和const限定符,同时出现,放在const后
即const &
- 定义多个同名同参的成员函数,则要么必须对所有函数加上引用限定符(不同的),要么都不加. 但
const
限定符没有这个要求
0 0
- CppPrimer笔记 Chapter13 拷贝控制
- 读书笔记:C++ primer 5th edition--chapter13.拷贝控制
- CppPrimer笔记 Chapter6 函数
- CppPrimer笔记 Chapter7 类
- CppPrimer笔记 Chapter8 IO库
- CppPrimer笔记 Chapter9 顺序容器
- CppPrimer笔记 Chapter11 关联容器
- CppPrimer笔记 Chapter12 动态内存
- VC++深入详解·chapter13·笔记
- 《算法导论》学习笔记之Chapter13红黑树
- CppPrimer笔记 Chapter10 泛型算法
- CppPrimer笔记 Chapter15 面对对象程序设计
- CppPrimer笔记 Chapter17 标准库特殊设施
- CppPrimer笔记 Chapter19 特殊工具与技术
- C++primer学习笔记----拷贝控制
- C++primer阅读笔记----------拷贝控制
- 《JavaScript高级程序设计》笔记——chapter13 事件
- CppPrimer笔记 Chapter14 重载运算与类型转换
- ArcMap中提取影像数据边界
- java中的Iterator和Iterable 区别
- 解决PDO-mysql中LIMIT和IN子句执行失败的问题
- Runtime
- 将图片写入流,通过流的方式在界面显示
- CppPrimer笔记 Chapter13 拷贝控制
- C++Primer笔记--变量和基本类型
- java 面试题
- leetcode110. Balanced Binary Tree
- Leetcode 142. Linked List Cycle II
- Java学习日记7:文件上传和下载
- 一个测试网站负载的工具--webbench
- 初步认识jQuery
- unity3d中实现相机的跟随