摘要

移动语义是C++11的新特性之一,利用移动语义可以实现对象的移动而非拷贝。在某些情况下,可以大幅度的提升性能。本文将介绍C++11移动语义中的一些基本概念。

表达式

表达式是由一个或者多个运算对象组成,对表达式求值将得到一个结果,字面值和变量是最简单的表达式,其结果就是字面值和变量的值。把一个运算符和一个或者多个运算对象组合起来可以生成较为复杂的表达式。

左值和右值

左值:能够取得地址的表达式是左值。例如:常见的变量都是左值。又例如一般情况下的赋值表达式是左值(所以一般要求类中重载的赋值操作符要返回*this)。

右值:不能取地址的表达式是右值。例如函数的非引用返回值或者字面常量。(可以简单的理解,右值是没有名字,但是又确实被创建的临时变量)。

class A
{
}; //a为左值
A a; //getA函数返回右值
A getA()
{
return A();
} void setA(A a)
{ }
//实参A()为右值
setA(A())

右值引用

引用:变量的别名。有以下要点:1)对引用的操作与对变量的操作是完全一样的;2)定义引用的时候必须进行初始化,而且不能绑定到其他对象上去。

左值引用:常规引用,只能绑定到左值上(有的编译器可以绑定到右值,见下文例子)。

右值引用:必须绑定到右值的引用。由于右值通常是被临时创建、即将被销毁的对象,所以右值引用可以延长右值的生命周期,直到右值引用类型的变量超出作用域,右值引用类型的变量在销毁的同时,被引用的右值也一并销毁。

这里请注意:变量的类型和变量本身是左值还是右值没有关系(只要是变量,就都是左值,因为其有名字,可以取地址。)例如:不能将右值引用绑定到右值引用类型的变量,这很奇怪,但是实际确实如此:

//a为右值引用类型的变量
A&& a = getA(); //错误,a为左值,不能将左值绑定到右值引用上
A&& b = a;

上文提到有的编译器可以将右值绑定到左值引用上面,在vs2015中,

//vs2015中没有报错,将右值绑定到左值引用上面
A& a = getA();

在g++5.3.1,上述代码会报错,不能将右值绑定到左值引用上面。

可见,对于右值绑定到左值引用上面,不同的编译器的要求是不一样的,可以不必过分关注这些细节问题。右值最重要的使用场景是对象的移动,接下来的文章会进行介绍。

参考

C++ Primer(第5版)

最新文章

  1. 作为前端应当了解的Web缓存知识
  2. Python 判断字符串是否为数字
  3. 关于APK签名的一些东西
  4. express-7 请求和响应对象(2)
  5. [Android Tips] 8. Install apk on multiple connected devices
  6. public static void main(String[] args){}函数理解
  7. BZOJ 1072: [SCOI2007]排列perm 状态压缩DP
  8. java web基础2HTTP协议知识点总结
  9. CentOS内核编译
  10. poj 1679 http://poj.org/problem?id=1679
  11. iOS之深入了解控制器View的加载
  12. 【PHP】PHP5.4.0版本号ChangeLog具体解释(上)
  13. Markdown简易语法说明
  14. PHP 静态缓存
  15. SVN服务端和客户端的安装与搭建
  16. 细说shiro之三:在独立应用中使用shiro
  17. Javaweb——————sql常用思维导图
  18. Debug.Assert vs Exception Throwing(转载)
  19. shell中uniq与sort -u 两种去重的对别
  20. 下单快发货慢:一个 JOIN SQL 引起 SqlClient 读取数据慢的奇特问题

热门文章

  1. shell脚本之判断当前内核主版本是否为3,且次版本是否大于10
  2. 私有化轻量级持续集成部署方案--04-私有代码仓库服务-Gitea
  3. CPU、进程、线程原理
  4. docker安装、基本使用、实战(测试必备)
  5. sql注入代码分析及预防
  6. json系列(一)cjson,rapidjson,yyjson解析示例
  7. 【C# IO 操作 】IFormatProvider接口|IFormattable 接口 格式化接口
  8. 在不受支持的 Mac 上安装 macOS Monterey 12(OpenCore Patcher)
  9. Oracle之非关系数据库
  10. 教程6--配置ssh