zoukankan      html  css  js  c++  java
  • c++11 右值引用

    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)

  • 相关阅读:
    HADOOP_HIVE安装和配置
    LInux__增加交换空间(SWAP)的大小
    ORACLE__Linux下Oracle数据库的卸载、删除
    HADOOP__HBASE集群安装(自带ZOOKEEPER)
    HADOOP__PIG安装与配置
    HADOOP__HADOOP基础安装和配置
    PYTHON__Thread达到上限的解决方案(设置线程上限)
    MYSQL__MYSQL的一些基础设置
    Android Studio Unable to access Android SDK addon list Mac
    dmg 文件打不开,双击没反应
  • 原文地址:https://www.cnblogs.com/sssblog/p/11383966.html
Copyright © 2011-2022 走看看