C++11 move语意
C++11引入了move语义,stl中的容器基本都支持move语义,因此我们在使用stl中的容器的时候,就已经使用过move语义了,在网上看了不少关于move语义的文章,发现要讲move,左值和右值是必须讲的,那我们首先就来说说这个左值和右值。
左值和右值(c++中的左值与右值)
在
C中,左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式)
在C++中,对于内置的类型,右值是不可被修改的,也不可被 const, volatile
所修饰;对于自定义的类型(user-defined
types),右值却允许通过它的成员函数进行修改,其他同C一样,至于有些文章上说:左值就是可以取地址的,而右值不可取地址,个人认为这是不对的。
Move语义
先举个例子,这个例子也是最简单容易理解的
vector doubleValues (const vector& v)
{
vector new_values( v.size() );
for (auto itr = new_values.begin(), end_itr = new_values.end(); itr != end_itr; ++itr )
{
new_values.push_back( * *itr );
}
return new_values;
}
调用函数doubleValues时是有两次复制的,一次是在函数返回时,因为local变量要被回收,所以需要copy构造一个临时对象来返回,当返回这个临时对象后,又需要一次copy赋值操作来赋值给其他变量。你可能会说,不返回对象就可以啊,可以返回一个引用或者一个指针,但是要这样做就得分配内存,但是C++的一个设计目标就是尽量少分配内存。上述更糟糕之处在于,返回的临时对象使用完之后是会被销毁掉的。
右值引用的一个用处是可以用来创建move构造函数和move赋值操作符,当出现上述的情况时,不会调用赋值构造函数或者拷贝构造函数,而是调用move类型的拷贝或者赋值构造函数。
如果使用的是stl中的容器,那么move是默认支持的,在一些特殊情况下,move比引用更好,更能提高代码性能,相信在C++11之后,move是一大趋势,不过这对C++程序员的要求又提升不少。比如要实现自己的类,最好提供move版的拷贝和赋值构造函数,类似如下声明:
Class(const Class& other)
Class(Class&& other)
如果一个类提供了如上的拷贝构造函数,那么当其是右值引用的时候,就会调用类似上述第二种拷贝构造函数,而右值引用的拷贝构造函数在拷贝的时候,只拷贝起指针,而指针指向的东西是不会被拷贝的,因为右值引用的变量(这样叫可能不合理)编译器确定后边是不会在用到,比如文中返回stl::vector数组的情况,不论是变量values还是临时拷贝的返回值都在后续中不会被使用。
注:文中的文章链接,都是个人觉着不错的文章,对作者在理解一些概念上又很大帮助,提供出来也是为了大家能更好的理解。
C++11 move语意的更多相关文章
- c++11——move/forward
std::move c++11中提供了std::move()来将左值转换为右值,从而方便的使用移动语义.move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝. c ...
- c++11 move构造函数和move operator 函数 学习
先看个代码吧!!!!!!!!!! #include <iostream> using namespace std; class A { public: A(){cout<<&q ...
- 【C/C++】C++11 Move, Forward
左值与右值 Lvalue:可以出现在 operator= 左边的 Rvalue:只能出现在operator= 右边的 ; int a = b; a = b; a = a + b; a + b = a; ...
- C++11右值引用和std::move语句实例解析
关键字:C++11,右值引用,rvalue,std::move,VS 2015 OS:Windows 10 右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践 ...
- 【编程篇】C++11系列之——临时对象分析
/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...
- C++ 11 之学习总结
感慨时间过的好快,C++ 11出来都5年了,现在才开始学习,但为时也不晚: 主要是网上及身边的朋友大肆宣扬C++ 11的某些优化,弄得别人心里痒痒的,所以就花了3天学习了点基本知识,相对于整个C++ ...
- C++11新特性之0——移动语义、移动构造函数和右值引用
C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...
- C++11标准之右值引用(rvalue reference)
1.右值引用引入的背景 临时对象的产生和拷贝所带来的效率折损,一直是C++所为人诟病的问题.但是C++标准允许编译器对于临时对象的产生具有完全的自由度,从而发展出了Copy Elision.RVO(包 ...
- C++11 之 delete 和 default
1 特殊成员函数 设计一个类,没有成员函数 (member function),只有数据成员 (member data) class DataOnly { private: std::string ...
随机推荐
- python函数默认参数陷阱
对于学习python的人都有这样的困惑 def foo(a=[]): a.append(5) return a Python新手希望这个函数总是返回一个只包含一个元素的列表:[5].结果却非常不同,而 ...
- Solr的配置和在java中的使用
Solr是一个全局站内搜索引擎,可以快速的搜索出结果. Solr依赖于tomcat,把Solr的war包放到tomcat中即可运行. 使用solr,需要在solr的schema.xml中配置solr与 ...
- Ducci 队列 -基础queue,set
https://vjudge.net/contest/185301#problem/B 用队列记录,set的不重复性来判断 //#include<bits/stdc++.h> #inclu ...
- 背包问题——dfs
背包问题——dfs 问题描述 解决思路 采用DFS搜索 其实也是回溯法 代码实现 #include<iostream> #include<vector> using nam ...
- soapUI启动报错:The JVM could not be started. The maximum heap size (-Xmx) might be too large or an antivirus or firewall tool could block the execution.
版本: soapUI-5.2.1 问题: 启动soapUI时报错:The JVM could not be started. The maximum heap size (-Xmx) might be ...
- Python算术运算
一.算术运算1.四则运算1+(100-20)/4+5*22.乘方运算2**103.求摸运算7%5 4.取整运算 7//5 = 1 5.绝对值函数 abs(-100) 6.导入数学函数后才能执行类似 ...
- 如何设置body高度为浏览器高度
html{height:100%} body{min-height:100%} 有时我们的页面上内容不多,但设计师要求背景色必须铺满全屏,这时候只需在样式表中加上这行,body就以浏览器的高度显示,超 ...
- PIL库自我学习总结及应用(美白,磨皮,搞笑图片处理)
Hello!今天我们来学习一下这个神奇的图片处理的第三方函数库——PIL库 (本blog部分图片及代码来自网络) 这是一个支持图像存储.显示和处理的函数库,它能够处理几乎所有图像格式,可以完成对图像的 ...
- group by 多个字段
众所周知,group by 一个字段是根据这个字段进行分组,那么group by 多个字段的结果是什么呢?由前面的结论类比可以得到,group by 后跟多个子段就是根据多个字段进行分组 注:下面的例 ...
- 购物车自己sql错误
$user_id=$_GET['user_id']; if(!$user_id){ $arr=array('code'=>-1,'data'=>"用户不存在"); ec ...