摘要

移动语义是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版)

C++11移动语义之一(基本概念)的更多相关文章

  1. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  2. c++ 11 移动语义

    C++ 已经拥有了拷贝构造函数, 和赋值函数,它们主要定位为浅和深度拷贝, 新增加一个移动构造函数,主要避免拷贝构造. 在定义了移动构造函数的情况下,在实参(argument)是一个右值(rvalue ...

  3. c++11 移动语义move semantics

    performance, expensive object copies move semantics, temporary objects implemented with rvalue refer ...

  4. [18/11/7] Java的基础概念

    java语言的优势是跨平台 ,计算机界的英语,是IT行业的第一大语言 特点是多线程 分布式 健壮性 面向对象 java和JavaScript的关系 雷锋和雷峰塔的关系 或卡巴斯基和巴基斯坦的关系有个基 ...

  5. 对C++11中的`移动语义`与`右值引用`的介绍与讨论

    本文主要介绍了C++11中的移动语义与右值引用, 并且对其中的一些坑做了深入的讨论. 在正式介绍这部分内容之前, 我们先介绍一下rule of three/five原则, 与copy-and-swap ...

  6. Jena语义Web开发101

    2015/05/28更新 代码在 https://github.com/zhoujiagen/semanticWebTutorialUsingJena 前言 该手册参考和扩展“Hebeler J, F ...

  7. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  8. C++ 11 学习2:空指针(nullptr) 和 基于范围的for循环(Range-based for loops)

    3.空指针(nullptr) 早在 1972 年,C语言诞生的初期,常数0带有常数及空指针的双重身分. C 使用 preprocessor macroNULL 表示空指针, 让 NULL 及 0 分别 ...

  9. C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

    这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...

随机推荐

  1. 一文带你解读Spring5源码解析 IOC之开启Bean的加载,以及FactoryBean和BeanFactory的区别。

    前言 通过往期的文章我们已经了解了Spring对XML配置文件的解析,将分析的信息组装成BeanDefinition,并将其保存到相应的BeanDefinitionRegistry中,至此Spring ...

  2. ASP.NET Core 6框架揭秘实例演示[09]:配置绑定

    我们倾向于将IConfiguration对象转换成一个具体的对象,以面向对象的方式来使用配置,我们将这个转换过程称为配置绑定.除了将配置树叶子节点配置节的绑定为某种标量对象外,我们还可以直接将一个配置 ...

  3. scanf坑我的那些年

    scanf函数作为用户输入指令给计算机的一种输入方法,它的使用有如下几被坑点: scanf用法:#include<stdio.h>;scanf("格式控制符",地址表列 ...

  4. k8s节点简介、移除节点、新增节点

    简介 Node是Pod真正运行的主机,可以是物理机也可以是虚拟机. Node本质上不是Kubernetes来创建的, Kubernetes只是管理Node上的资源. 为了管理Pod,每个Node节点上 ...

  5. Three.js之绘制中文文字并跟随物体

    本周更新的需求是物体上显示文字信息,效果图如下: 加载字体 import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'; ...

  6. C# 2进制、8进制、10进制、16进制...各种进制转换

    在.NET Framework中,System.Convert类中提供了较为全面的各种类型.数值之间的转换功能. 其中的两个方法可以轻松的实现各种进制的数值间的转换: Convert.ToInt32( ...

  7. C#中default 、base 、this关键字用法简介

     C#中default关键字用法简介 default 关键字可在switch语句或泛型代码中使用.switch语句:指定默认标签.泛型代码:指定类型参数的默认值.对于引用类型为空,对于值类型为零swi ...

  8. 基于IEC61499标准的组件

    IEC 61499标准通常用于开发分布式控制系统.IEC 61499定义了功能模块(FB, function block)的模型.有三种FB,分别是Basic FB (BFB),Service Int ...

  9. Nginx平滑升级的详细操作方法

    转至:https://blog.csdn.net/midion9/article/details/49684325 一.平滑升级概述Nginx方便地帮助我们实现了平滑升级.其原理简单概括,就是:(1) ...

  10. MyEclipse 启动tomcat本地服务,debug模式,代码一直不同步

    今天写代码遇到一个问题,上午还能正常运行的代码,在eclipse中显示正常,但在游览器中就出现了差异,在网上找了很多方法: 1.add and remove项目,清理tomcat部署目录下的项目,清理 ...