第十三章笔记 拷贝控制

一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数(copy construcor),拷贝赋值运算符(copy-assignment operator)、移动构造函数(move constructor)、移动赋值运算符(move-assignment operator)和析构函数(destructor)。

 

1.拷贝构造函数

1.拷贝构造函数的第一个参数必须是一个引用类型。

 

2.如果我们没有给一个类定义拷贝构造函数,则编译器会定义一个合成拷贝构造函数。(大致就是编译器自己整的就叫合成拷贝构造函数)

 

3.直接初始化,实际上是要求编译器使用普通的函数匹配来选择与我们提供的参数最匹配的构造函数。

   拷贝初始化,相当于将右侧运算对象拷贝到正在创建的对象中,如果需要还要进行类型转换。

 

4.标准库通常要求保存在容器中的类型要具有赋值运算符,且返回值是左侧运算对象的引用。

2.析构函数

1.它是类的一个成员函数,名字由波浪号接类名构成。它没有返回值,也不接受参数。因此不能被重载,即对一个给定类,只会有唯一一个析构函数。

2.合成析构函数不会delete一个指针数据成员。

3.三/五法则

1.三个控制类拷贝操作的基本操作:拷贝构造函数,拷贝赋值运算符和析构函数(阻止拷贝)。

4.=default

我们只能对具有合成版本的成员函数使用=default。

5对某些类来说,编译器将这些合成的成员定义为删除的函数:

某个成员析构函数删除/不可访问->类的合成析构函数被定义为删除

某个成员的拷贝构造函数/某个成员的析构函数<---->类的合成拷贝构造函数被定义为删除

某个成员的拷贝赋值运算符->类的合成拷贝赋值运算符被定义为删除

某个成员的析构函数/类有个引用成员,没有类内初始化器->该类的默认构造函数定义为删除

即如果一个类有数据成员不能默认构造、拷贝、复制或销毁,则对应的成员函数将被定义为删除的。

6.自赋值

不是很懂自赋值是什么,书中举例是当要释放内存的对象与要拷贝的对象是同一个时,会使指针空悬,导致出错。

解决方法是通过拷贝和交换的赋值运算符,可以正确处理自赋值。

7.移动构造函数

如果没有移动构造函数,那么为一个vector重新分配内存的时候,就会引起从旧内存空间到新内存空间逐个拷贝string。

两个机制:1.假定string的移动构造函数进行了指针的拷贝,而不是为字符分配内存空间然后拷贝字符。

                  2.一个名为move的标准库函数,调用move来表示希望用string的移动构造函数;

8.对象移动

新标准的一个最主要的特性是可以移动而非拷贝对象的能力。

8.1  右值引用

a.右值引用只能绑定到一个将要销毁的对象。

b.一般而言,一个左值表示的是一个对象的身份,而一个右值表示的是一个对象的值。

c.不能将一个右值引用直接绑定到一个左值上。

int &r2=i*42     //错误

d.但我们可以将一个const的左值引用(常规引用)或者一个右值引用绑定到非引用类型的函数

const int &r3 = i * 42  //正确
int &&rr2 = i * 42     //正确

8.2 左值持久:右值短暂

二者的区别:左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。

使用右值引用的代码可以自由地接管所用的对象的资源。

我们不能将一个右值引用绑定到一个右值引用类型的变量上:(这是由于变量是左值)

int &&rr1 = 42;    //正确:字面常量是右值
int &&rr2 = rr1;   //错误:表达式rr1是左值!

但是我们可以通过调用一个名为move的新标准库函数来获得绑定到左值上的右值引用

int &&rr3 = std::move(rr1);    //ok

调用move就意味着承诺:除了对rr1赋值或销毁它外,我们将不再使用它。

我们可以销毁一个移后源对象,也可以赋予它新值,但不能使用一个移后源对象的值

8.3 移动迭代器

与一般的迭代器解引用运算符返回一个指向元素的左值不同,移动迭代器的解引用运算符生成一个右值引用。

只有当确信算法在为一个元素赋值或将其传递给一个用户定义的函数后不再访问它时,才能将移动迭代器传递给算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值