C++Primer 第十三章
//1.当定义一个类时,我们显示地或隐式地指出在此类型的对象(注意这里是此类型的对象,而不包括此类型的指针)拷贝,移动,赋值,销毁时做什么。一个类通过定义五种特殊的成员函数来控制这些操作:拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符,析构函数。
//当定义了五种特殊成员函数的其中一个的时候,一般也需要定义其他几个操作。
//拷贝构造函数的第一个参数必须是一个引用类型,若第一个参数不是引用类型则会造成逻辑错误:传值调用会产生一个临时对象,而此对象必须通过类的拷贝构造函数生成,所以会陷入死循环 //2.类的转换构造函数会自动调用。
CMyString(char *temStr) : str(temStr){printf("b0");}
CMyString str0 = "s0"; //这里将调用类的转换构造函数 //3.类的赋值运算符应该返回一个指向其左侧运算符对象的引用。返回左侧对象是为了能连续赋值,返回引用是为了提高效率。 //4.在一个析构函数中,首先执行函数体,然后按照成员初始化顺序逆序销毁成员。当在一个容器销毁其元素时,容器中的元素会自动执行其析构函数。
// 当指向一个对象的引用或指针离开作用域的时候,其指向类型的析构函数不会被调用。当一个动态分配的类类型指针,其被delete的时候,其指向类型的析构函数会被调用。
// 当一个类需要定义析构函数的时候,一般来说也需要定义其他的拷贝操作。
// 当一个类的析构函数被定义为不可访问的时候,不允许定义此类的对象。可以动态分配这种类型的对象,但是不能释放它。 //5.合成的拷贝控制成员可能是删除的:
A:如果类的某个成员的析构函数是删除或者不可访问的,则类的合成析构函数和类的合成拷贝构造函数被定义为删除的。
B:如果类的某个成员的拷贝构造函数是删除或不可访问的,则类的合成拷贝构造函数被定义为删除的。
C:如果类的某个成员的拷贝赋值运算符是删除或不可访问的,或是类有一个const或引用成员,则类的合成拷贝赋值运算符被定义为删除的。
D:如果类的某个成员的析构函数是删除或是不可访问的,或类有一个引用成员并且没有类内初始化器,或者类有一个const成员没有类内初始化器且类型没有指定默认构造函数,则该类的默认构造函数被定义为删除的。
总结:如果类的数据成员不能默认构造,拷贝,复制,销毁,则对应的成员函数将被定义为删除的。 //6.在private中声明类的拷贝构造函数等系列函数,并且不定义此类型函数,可以防止此类型对象被拷贝。注意点:不能定义,否则类的成员函数或者类的友员仍然能访问这些函数。 //7.赋值运算符通常组合了析构函数和拷贝构造函数的操作。注意点:如果将对象赋予其本身,赋值运算符必须能正常工作。 //8.通过&&来获得右值引用,右值引用有一个特殊性质:只能绑定到即将销毁的对象上(不能将右值引用直接绑定在左值上),来实现资源的移动。
// 左值持久,右值短暂。由于右值引用变量本身是一个左值变量,所以不能将右值引用绑定到右值引用对象上。
// 可以通过std::move函数来获得绑定到左值上的右值引用。此函数定义在头文件utility。声明在命名空间std中。
// move调用告诉编译器:我们有一个左值,但是我们希望像一个右值一样处理它。在调用move后就意味着承诺:对被调用变量,除了赋值或销毁外,我们将不再使用它。在调用std::move后,对被调用变量的值不能做任何假设。
// 使用move的时候,用如下方法:std::move。这样可以防止潜在的命名冲突。
// 当我们编写一个移动操作的时候,从一个对象移动资源而并不会销毁此对象,所以必须确保移后源对象进入一个有效的且可析构状态。
// 由于移后源对象具有不确定状态,所以当我们调用move后,必须绝对确认移后源对象没有其他用户。在代码中小心使用move可以极大的提高性能。 //9.当没有定义自己的移动操作的时候,通过函数匹配,会调用对应的拷贝操作版本。
// 只有当一个类没有定义任何自己版本的拷贝控制成员的时候,且类的每个非static成员都可以移动的时候,编译器才会定义移动控制成员。
// 当类定义了自己的移动操作后,会将其对应的默认拷贝操作定义为删除的。 //10.make_move_iterator:将普通迭代器转为移动迭代器。make_move_iterator定义在头文件iterator中。声明在命名空间std中。
allocator<unique_ptr<char>> allocStr;
auto pStr = allocStr.allocate();
vector<unique_ptr<char>> vecStr();
generate(vecStr.begin(), vecStr.end(), [](){return (unique_ptr<char>)new char();});
//uninitialized_copy(vecInt.begin(), vecInt.end(), pStr); //此句代码非法。unique_ptr对象是不可拷贝的
uninitialized_copy(make_move_iterator(vecStr.begin()), make_move_iterator(vecStr.end()), pStr); //正确执行,将vecStr的资源移动到了pStr所指向的内存中。 //11.如果一个成员函数同时提供拷贝和移动版本,也能提高性能。
// void push_back(_Ty&& _Val) :接受右值引用版本,来移动资源。对于存储unique_ptr类型的元素的容器的push_back操作就是调用此版本。
// void push_back(const _Ty& _Val) :此版本是拷贝版本。
C++Primer 第十三章的更多相关文章
- C++ Primer : 第十三章 : 拷贝控制之对象移动
右值引用 所谓的右值引用就是必须将引用绑定到右值的引用,我们通过&&来绑定到右值而不是&, 右值引用只能绑定到即将销毁的对象.右值引用也是引用,因此右值引用也只不过是对象的别名 ...
- C++ Primer : 第十三章 : 动态内存管理类
/* StrVec.h */ #ifndef _STRVEC_H_ #define _STRVEC_H_ #include <memory> #include <string> ...
- C++ Primer : 第十三章 : 拷贝控制示例
/* Message.h */ #ifndef _MESSAGE_H_ #define _MESSAGE_H_ #include <iostream> #include <strin ...
- C++ Primer : 第十三章 : 拷贝控制之拷贝控制和资源管理
定义行为像值的类 行为像值的类,例如标准库容器和std::string这样的类一样,类似这样的类我们可以简单的实现一个这样的类HasPtr. 在实现之前,我们需要: 定义一个拷贝构造函数,完成stri ...
- C++ Primer : 第十三章 : 拷贝控制之拷贝、赋值与销毁
拷贝构造函数 一个构造函数的第一个参数是自身类类型的引用,额外的参数(如果有)都有默认值,那么这个构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是一个引用类型. 合成的拷贝构造函数 在我们没 ...
- 【C++ Primer 第十三章】4. 拷贝控制示例
拷贝控制示例 #include<iostream> #include<string> #include<set> #include<vector> us ...
- C++ Primer Plus学习:第十三章
第十三章 类继承 继承的基本概念 类继承是指从已有的类派生出新的类.例: 表 0-1 player.h class player { private: string firstname; string ...
- 【C++】《C++ Primer 》第十三章
第十三章 拷贝控制 定义一个类时,需要显式或隐式地指定在此类型地对象拷贝.移动.赋值和销毁时做什么. 一个类通过定义五种特殊的成员函数来控制这些操作.即拷贝构造函数(copy constructor) ...
- PRML读书会第十三章 Sequential Data(Hidden Markov Models,HMM)
主讲人 张巍 (新浪微博: @张巍_ISCAS) 软件所-张巍<zh3f@qq.com> 19:01:27 我们开始吧,十三章是关于序列数据,现实中很多数据是有前后关系的,例如语音或者DN ...
随机推荐
- MVC validation
<div class="editor-field"> @Html.TextBoxFor(m => m.DateField) @Html.ValidationMes ...
- Selenium 遇到的问题
1. How to Resolve Stale Element Reference Exception? First of all lets be clear about what a WebElem ...
- 【转】全面解析Unity3D自动生成的脚本工程文件
http://blog.csdn.net/jjiss318/article/details/7632041 我们在Unity3D开发的时候,经常会看到它会产生不少固定命名工程文件,诸如: Assemb ...
- 【转】PHP框架性能测试报告 - ThinkPHP 3.2.3 Laravel 5.2 Yii2.0.5
作为一个PHP开发者,而且是初创企业团队的技术开发者,选择开发框架是个很艰难的事情. 用ThinkPHP的话,招聘一个刚从培训机构出来的开发者就可以上手了,但是性能和后期代码解耦是个让人头疼的事情.不 ...
- java endorsed
endorsed目录,充许你将一些特殊的类库放到其中以供项目使用. 官方说明: Specifying the -Djava.endorsed.dirs=lib/endorsed system p ...
- Http请求工具
package cn.com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...
- Region的预分区
1.预分区的方式 共有四种方式 2.帮助信息 help 'create' 3.第一种方式 4.在页面上查看效果(端口号:60010) 5.第二种方式 )创建文件,并在文件中书写分区的值 )创建表 6. ...
- BeanNameViewResolver
As described in the documentation, BeanNameViewResolver resolves Views declared as beans. Usually yo ...
- ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click 'Restart'
ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click ...
- JS懒加载
4.如何使用js懒加载图片 a.懒加载图片是基于jquery.js的,所以: <script src="jquery.js" type="text/ja ...