拷贝控制
2016-02-20 15:32
169 查看
1.拷贝控制操作
拷贝构造函数移动构造函数 //用同类型的对象初始化本对象
拷贝赋值运算符
移动赋值运算符 //将一个对象赋予同类型的另一个对象
析构函数 //销毁对象
注意点:
①如果一个类没有定义所有这些拷贝控制成员,编译器会自动为它定义缺失的操作。
②声明后加=default来显示要求编译器生成合成的版本,只能对具有合成版本的成员函数使用(默认构造函数&拷贝控制成员)。
③声明后加=delete来定义删除的函数,来阻止该函数的调用,可以对任何函数使用,与=default不同。
④< utility >头文件中的move函数调用均采用std::move
⑤swap(a,b); //若a和b均为内置类型,此时会调用标准库std::swap,否则按照匹配程度最优的调用
class A { public: A(const A &a){} //拷贝构造函数 A(const A &&a){} //移动构造函数 A& operator=(const A &a){} //拷贝赋值运算符 A& operator=(const A &&a){} //移动赋值运算符 ~A(){} //析构函数 };
2.拷贝构造函数
定义:构造函数的第一个参数为自身类类型的引用,且任何额外参数都有默认值。编译器生成的合成拷贝构造函数为浅拷贝。使用拷贝构造函数的情况:
①用=定义变量时 //Ta = b;
②非引用参数传递 // fcn(T v); fcn(a); 这也是参数第一个为&的原因,否则出现死循环
③非引用函数返回 // fcn(){… return v;}
④列表初始化数组元素 // T arr[size] = {…}
⑤容器元素用非emplace添加 // insert()|push()
⑥直接初始化时编译器根据参数匹配调用 // T a(b);编译器使用普通函数匹配
3.拷贝赋值运算符
A a1,a2; a1 = a2; //将一个对象赋予同类型的另一个对象
合成的拷贝赋值运算符类似合成的拷贝构造函数。
4.析构函数
当变量离开作用域、对象销毁时成员销毁、容器销毁时其元素销毁、delete对象指针,析构函数调用,成员按初始化的逆序销毁。一个类自定义了析构函数,基本也需要自定义拷贝赋值运算符和拷贝构造函数,反过来却不一定。
5.移动构造函数和移动赋值运算符
从给定对象窃取资源而不是拷贝资源(指针的移交,之前的指针变量需置nullptr),一般均声明为noexcept(不抛异常,置于参数列表与初始化列表开始的:中间)如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或析构函数,编译器就不会为它合成移动构造函数和移动赋值运算符了。
移动迭代器解引用生成一个右值引用,通过调用标准库的make_move_iterator函数可将一个普通迭代器转换为一个移动迭代器。copy(make_move_iterator(b),make_move_iterator(e),d);
6.简易的SmartPoint
template<typename T> class SmartPoint { public: SmartPoint():users(new size_t(1)),p(new T()){} //默认构造函数 explicit SmartPoint(T *q):users(new size_t(1)),p(q){} //内置指针构造函数 SmartPoint(const SmartPoint &sp):users(sp.users),p(sp.p){++*users;} //拷贝构造函数 SmartPoint& operator=(const SmartPoint &sp); //赋值运算符重载 ~ SmartPoint(); //析构函数 private: size_t *users; T *p; }; template<typename T> SmartPoint<T>& SmartPoint<T>::operator=(const SmartPoint &sp) { ++*sp.users; //先对右边指针引用计数+1,解决自我复制存在的问题 if (--*users==0) { delete users; delete p; } users = sp.users; p = sp.p; return *this; } template<typename T> SmartPoint<T>::~ SmartPoint() { if (--*users==0) { delete users; delete p; } }
7.引用限定符
引用限定符可以为&或&&(成员函数参数列表后),且必须同时出现在函数的声明和定义中。可以和const结合使用,const限定符置前,引用置后,二者均可以作为重载区分。
&表示仅能通过左值调用该函数,&&表示仅能通过右值调用该函数,const &均可。
如果一个成员函数有引用限定符,则具有相同参数列表的所有版本都必须有引用限定符。
相关文章推荐
- Nginx(一):静态资源web服务器配置详解
- 基本语句的综合运用
- css3 animation 中的 steps
- awk
- 【BZOJ1226】【SDOI2009】学校食堂
- 谈Objective-C Block的实现
- LeetCode 203. Remove Linked List Elements 解题报告
- centos7 opera济览器安装
- 程序加载中,请稍后...progressDialog的使用
- centos7 opera济览器安装
- 直接下载adobe的完整安装包
- solr-4.10.4环境搭建+导入数据库+中文分词
- 【炼数成金-推荐系统笔记】
- Java修饰符public,private,protected及默认的区别
- 2016太原网络营销师sem(百度竞价)账户搭建问题解剖?
- 关于函数调用方式`__stdcall`和`__cdecl`
- 项目经理评分
- HDR 拍照模式的原理,实现及应用
- 数字图像处理--显示图像矩阵出现的问题
- 悲观锁及乐观锁的引用