C++11移动语义之一(基本概念)

摘要

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

时间: 2024-12-16 22:33:53

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

c++11 移动语义

c++11 移动语义 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> // C++中还有一个被广泛认同的说法,那就是可以取地址的.有名字的就是左值,反之,不能取地址的.没有名字的就是右值. // 相对于左值,右值表示字面常量.表达式.函数的非引用返回值等. /* 右值引用是用来支持转移语义的. 转移语义

Css3之基础-11 Css定位(定位概念 、定位方式)

一.CSS 定位概述 定位概念 - 普通流定位 - 页面中的块级元素框从上到下一个接一个地排列 - 每一个块级元素都会出现在一个新行中 - 内联元素将在一行中从左到右排列水平布置 - 浮动 - 相对定位 - 绝对定位 - 固定定位 定位属性 - position属性: - position: static/relative/absolute/fixed; - 偏移属性:实现元素框位置的偏移 - top/bottom/right/left: value; - 堆叠顺序 - z-index: val

C++11:移动语义与完美转发

转自 https://www.cnblogs.com/jianhui-Ethan/p/4665573.html C++11 引入的新特性中,除了并发内存模型和相关设施,这些高帅富之外,最引人入胜且接地气的特性就要属『右值引用』了(rvalue reference).加入右值引用的动机在于效率:减少不必要的资源拷贝.考虑下面的程序: std::vector<string> v; v.push_back("string"); 首先看push_back: push_back(co

C++11 move 语义

首先认识3种拷贝构造函数:1.默认的拷贝构造函数: 2.自己定义的拷贝构造函数: 3.move拷贝构造函数: typedef struct MyTest{ int a; int b; float c; int * d; MyTest ():a(1),b(2),c(2.2){ d = new int[10]; for(int i = 0;i<10;i++){ d[i] = i; } } ~MyTest(){ delete []d; } }MyTest; 对于这么个结构体 默认的构造函数,就会依次对

18 11 16 网络通信 ---- 多线程 同步概念 解决资源互斥的问题

---恢复内容开始--- 在多任务中  由于线程是分步执行  所以在很多线程执行的时候 会对全局变量造成很大的影响  如图中 线程一执行完一二步中 跳过第三部  而跑到线程二去执行 就会造成  全变量不稳定 引进   上锁 功能可以 不仅多线程 还能 把一个运行完再到下一个 import threading import time # 定义一个全局变量 g_num = 0 def test1(num): global g_num # 上锁,如果之前没有被上锁,那么此时 上锁成功 # 如果上锁之前

HTML5学习笔记(三):语义化和新增结构元素

在HTML5之前,使用机器来阅读一个网页是非常困难的,我们使用不同样式的div来标记不同的内容,所以实际上机器无法得知页面的哪个部分是正文,哪个部分是标题,那么在HTML5里,针对这个问题就引入了语义化的概念,同时提供了新的标签来指定对应的内容类型. 语义化的好处 语义化的html只用来搭建网页的结构,去掉css后,网页结构不会变: 屏幕阅读器(如果访客有视障)会完全根据你的标记来“读”你的网页: 搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重: 你的页面是否对爬虫容易理解非常重要,因

《使用 C++11 编写 Linux 多线程程序(转载收藏)》

转载自: http://www.ibm.com/developerworks/cn/linux/1412_zhupx_thread/ 本文讲述了如何使用 C++11 编写 Linux 下的多线程程序,如何使用锁,以及相关的注意事项,还简述了 C++11 引入的一些高级概念如 promise/future 等. 前言 在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web

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

这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理解C++ 11中这些比较重要的特性. 关于左值和右值的定义 左值和右值在C中就存在,不过存在感不高,在C++尤其是C++11中这两个概念比较重要,左值就是有名字的变量(对象),可以被赋值,可以在多条语句中使用,而右值呢,就是临时变量(对象),没有名字,只能在一条语句中出现,不能被赋值. 在 C++1

HTML语义化的理解

一.HTML语义化的概念 1.主要的标签,有标题(H1~H6).列表(li).强调(strong em)等 2.根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读,以及在写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析. 二 .语义化的必要 1.为了在没有CSS的情况下,页面也能呈现出很好地内容结构.代码结构: 2.提升用户体验 例如 : title.alt用于解释名词或解释图片信息.label标签的使用 3.有利于SEO优化 1)搜索引擎建立良好沟通,有助于爬虫抓取