C++11-从Rvalue references(右值引用)到move的设计

Rvalue reference右值引用—减少不必要的复制在这里插入图片描述

(1)当copy的右手边来源端是右值,那么左值可以“偷”右手边resource而不需要执行allocation;
(2)左值和右值的差别:1、左值是变量;2、不能放在左手边的就是右值;
(3)string是一个指针,对于string的红色测试都通过编译了,表达式s1+s2,临时对象string()都通过了!!!
(4)对于complex的测试也通过了测试!!!complex没有指针哦!

C++2.0对右值&取地址的新语法

在这里插入图片描述
(1)&foo()有()因此是对函数返回值来取地址,而函数返回值是一个右值,因此不能对右值取地址;函数名就是函数的地址
(2)C++2.0可以对右值取地址,引用reference;
在这里插入图片描述

  • c.insert(it,Vtype(buf))如果这个Vtype(buf)临时对象有指针的话,可以“偷”,但是要有一种明确指令可以允许“偷”的行为;
  • C++2.0的inset有两个版本,除了copy还有move版本insert(,&& x);
    作为右值引用的类型的拷贝构造函数也需要对应两个版本,分别是copy拷贝构造和move拷贝构造;copy拷贝构造是深拷贝是真的会分配一个新内存;move拷贝构造Mystring(Mystring&& str),不需要新分配(指针的浅拷贝),只是将指针复制过去;两个指针指向同一个内存,是危险的操作;因此,原指针就被打叉就不能再调用(转让所有权!!!);但是右值本来就是临时对象,之后也并不会被继续使用;
  • 如果是左值,但是程序员知道以后不会再使用,将其作为右值,一种语法就是M c2(std::move(c1)),相当于告诉编译器是右值引用rvalue reference;

Rvalue reference 和 Move Semantics的代码实现

在这里插入图片描述
(1)容器vector的insert()中move版本实现,G2.9是之前的insert,G4.9新增了moveb版本的insert();
(2)身为元素的MyString要写好自己的拷贝构造的两个版本;

unperfect forwarding 不完美的传递

在这里插入图片描述
(1)process(move(a))是告诉编译器请把a当做右值处理;
(2)在forward(2)测试时,forward正确调用了右值forward(int&&),但是在forward调用process(i)的时候,确调用的process(int &),而不是Process(int&&),称为“不完美的快递”;
(3)就像调用insert()函数之后insert()再调用元素的拷贝构造一样;会出现问题;

perfect forwarding 完美的传递

在这里插入图片描述

move设计

在这里插入图片描述
在这里插入图片描述
(1)copy和move依靠右值引用Rvalue reference来区分;
(2)注意在move constructor中,浅拷贝之后,将原来的len=0;data=NULL;注意这里不是将其delete,只是置为空指针,因为delete是由析构函数负责的;
而且一定要将其设置为NULL,因为如果原析构函数delete内存空间就被释放;
(3)move assignment相同,也是先进行长度和地址的浅拷贝,然后将之前的len=0;data=NULL;
(4)在析构函数中,会检查data是否为NULL,不是NULL才会delete;因为如下图中,Vtype(buf)是一个临时对象,复制完成后会调用其析构函数,要使用NULL将其连接打断,并且保存那块内存;并且其析构函数要判断,如果是NULL就不要delete,只是释放临时对象本身就可以;

move测试-对容器效率的影响

在这里插入图片描述
(1)测试vector容器,元素是Mystring带有move版本和MyStrNoMove版本的;
上图中,300万个Moveable元素放入vector容器中,调用移动构造函数700多万次,下方测试300万个non-moveable元素放入vector容器,调用赋值构造函数700多万次;
(2)因为两倍增长,把所有元素全部搬移,引发复制构造/移动构造,所以是700多万次;
在这里插入图片描述
在这里插入图片描述
(3)接着有对于List,deque,multiset差别不大,因为其链表或者红黑树结果,插入方便;没有vector不断增长两倍空间,不断搬移的情况;对于Copy constructor和Move contructor;
(4)其具体差异多少与当前内存破碎或连续情况而定;
(5)但是对于copy和move copy的差别一直都巨大!!
(6)目前看只有对vector影响巨大,但是对于deuqe,如果做从中间某一处插入的动作,两边元素会往外搬移,会出现大量的copy constructor也影响巨大;
(7)容器以节点形式存在,Copy constructor还是Move constructor影响不大;

vector中copy与move分析

在这里插入图片描述
在这里插入图片描述
(1)只是交换了指针,就很快,其实指向的是同一个内存块;
(2)而且因为vector其实只需要3个指针构成,元素头尾和空间尾;其实就是两组指针的交换;每组有3个指针;
(3)move测试是将整个容器对象c当成右值;容器c就之后就不可以再用了!!!
当你选择用Move()将源头看做右值时,就必须确定之后不会在使用!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值