文档章节

c++11 右值引用

o
 osc_wws45aot
发布于 2019/08/20 16:52
字数 712
阅读 8
收藏 0

精选30+云产品,助力企业轻松上云!>>>

1. 临时变量的拷贝

#include <iostream>

using namespace std;

class HasPtrMem {
  public:
    HasPtrMem() : d(new int(3)) {
      cout << "Construct: " << ++n_cstr << endl;
    }

    HasPtrMem(const HasPtrMem& h) : d(new int(*h.d)) {
      cout << "*Copy construct: " << ++n_cptr << endl;
    }

    HasPtrMem(HasPtrMem&& h) : d(h.d) {   //移动构造函数
      h.d = nullptr;
      cout << "Move construct: " << ++n_mvtr << endl;
    }

    ~HasPtrMem() {
      delete d;
      coout << "Destruct: " << ++n_dstr << endl;
    }

    int* d;
    static int n_cstr;
    static int n_dstr;
    static int n_cptr;
    static int n_mvtr;

};

int HasPtrMem::n_cstr = 0;
int HasPtrMem::n_dstr = 0;
int HasPtrMem::n_cptr = 0;
int HasPtrMem::n_mvtr = 0;

HasPtrMem GetTemp() {
  HasPtrMem h;
  cout << "Resource from " << __func__ << ": " << hex << h.d << endl;
  return h;
}

int main() {
  HasPtrMem a = GetTemp();
  cout << "Resource from " << __func__ << ": " << hex << a.d << endl;
  return 0;
}

使用g++编译,不使用优化:g++ -std=c++11 -fno-elide-constructors test.cpp -o main

输出为:

Construct: 1

Resource from GetTemp: 0x25d5c20

Move constructor: 1

Destruct: 1

Move constructor: 2

Destruct 2

Resource from main: 0x25d5c20

Destruct: 3

在移动构造函数中,h相当于临时变量的引用。该构造函数使用了参数h的成员d初始化了本对象的成员d,而h的成员d随后被置为指针空值nullptr。h.d和a.d都指向了相同的堆地址内存。

2. 左值、右值与右值引用

左值:可以被取地址的

右值:不能被取地址的

a = b + c;

&a是合法的,而&(b + c)不会通过编译。

在c++11中,右值由两个概念构成:一个是将亡值(xvalue, eXpiring Value),另一个是纯右值(pvalue, Pure Rvalue)。

纯右值是C++98中右值的概念,讲的是用于辨识临时变量和一些不跟对象关联的值。比如非引用返回的函数返回的临时变量值,一些运算表达式,比如1 + 3产生的临时变量值,而不跟对象关联的字面量值,2, ‘c’, true,也是纯右值。此外,类型转换函数的返回值,lambda表达式也是右值。

将亡值是将要被移动的对象,比如返回右值引用T&&的函数返回值、std::move的返回值或者转换为T&&的类型转换函数的返回值。剩余的,可以标识函数、对象的值都属于左值。在C++11的程序中,所有的值必属于左值、将亡值、纯右值三者之一。

只要是能够绑定右值的引用类型,都能够延长右值的生命期。

引用类型 可以引用的值类型 注记
非常量左值 常量左值 非常量右值 常量右值
非常量左值引用 Y N N N
常量左值引用 Y Y Y Y 全能类型,可用于拷贝语义
非常量右值引用 N N Y N 用于移动语义,完美转发
常量右值引用 N N Y Y 暂无用途

3. std::move 强制转化为右值

std::move是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值,以用于移动语义。等同于一个类型转换:

static_cast<T&&>(lvalue)

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

格式编号始终显示2个小数位 - Format number to always show 2 decimal places

问题: I would like to format my numbers to always display 2 decimal places, rounding where applicable. 我想将数字格式化为始终显示2个小数位,并在适用的情况下四舍五入。 Examples...

富含淀粉
47分钟前
22
0
Docker可视化工具Portainer

1 前言 从没想到Docker也有可视化的工具,因为它的命令还是非常清晰简单的。无聊搜了一下,原来已经有很多Docker可视化工具了。如DockerUI、Shipyard、Rancher、Portainer等。查看对比了一番...

南瓜慢说
49分钟前
20
0
日志系统新贵 Loki,真香!!

最近,在对公司容器云的日志方案进行设计的时候,发现主流的ELK或者EFK比较重,再加上现阶段对于ES复杂的搜索功能很多都用不上最终选择了Grafana开源的Loki日志系统,下面介绍下Loki的背景。...

庞陆阳
今天
14
0
jQuery获取select onChange的值 - jQuery get value of select onChange

问题: I was under the impression that I could get the value of a select input by doing this $(this).val(); 我的印象是我可以通过执行$(this).val();来获取选择输入的值$(this).val()......

javail
今天
13
0
道翰天琼解密宇宙信息大脑三者最核心奥秘,破解认知智能基础理论(群聊形式)

三体论是探索研究宇宙,信息和人类大脑三者关系的理论体系。是认知智能的奠基理论体系之一。宇宙和信息,信息和人类大脑,人类大脑和宇宙,三者之间存在着某种未被完全揭示的奥秘。三体论的核...

jackli2020
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部