加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++11 move函数 将左值强制变换为右值

发布时间:2022-07-14 06:04:13 所属栏目:语言 来源:互联网
导读:通过学习 《C++11移动构造函数》一节我们知道,C++11 标准中借助右值引用可以为指定类添加移动构造函数,这样当使用该类的右值对象(可以理解为临时对象)初始化同类对象时,编译器会优先选择移动构造函数。 注意,移动构造函数的调用时机是:用同类的右值
  通过学习 《C++11移动构造函数》一节我们知道,C++11 标准中借助右值引用可以为指定类添加移动构造函数,这样当使用该类的右值对象(可以理解为临时对象)初始化同类对象时,编译器会优先选择移动构造函数。
 
  注意,移动构造函数的调用时机是:用同类的右值对象初始化新对象。那么,用当前类的左值对象(有名称,能获取其存储地址的实例对象)初始化同类对象时,是否就无法调用移动构造函数了呢?当然不是,C++11 标准中已经给出了解决方案,即调用 move() 函数。
 
  move 本意为 "移动",但该函数并不能移动任何数据,它的功能很简单,就是将某个左值强制转化为右值。
  基于 move() 函数特殊的功能,其常用于实现移动语义。
 
  move() 函数的用法也很简单,其语法格式如下:
  move( arg )
 
  其中,arg 表示指定的左值对象。该函数会返回 arg 对象的右值形式。
 
  move() 函数的基础应用。
  #include <iostream>
  using namespace std;
  class movedemo{
  public:
      movedemo():num(new int(0)){
          cout<<"construct!"<<endl;
      }
      //拷贝构造函数
      movedemo(const movedemo &d):num(new int(*d.num)){
          cout<<"copy construct!"<<endl;
      }
      //移动构造函数
      movedemo(movedemo &&d):num(d.num){
          d.num = NULL;
          cout<<"move construct!"<<endl;
      }
  public:     //这里应该是 private,使用 public 是为了更方便说明问题
      int *num;
  };
  int main(){
      movedemo demo;
      cout << "demo2:n";
      movedemo demo2 = demo;
      //cout << *demo2.num << endl;   //可以执行
      cout << "demo3:n";
      movedemo demo3 = std::move(demo);
      //此时 demo.num = NULL,因此下面代码会报运行时错误
      //cout << *demo.num << endl;
      return 0;
  }
  程序执行结果为:
  construct!
  demo2:
  copy construct!
  demo3:
  move construct!
 
  通过观察程序的输出结果,以及对比 demo2 和 demo3 初始化操作不难得知,demo 对象作为左值,直接用于初始化 demo2 对象,其底层调用的是拷贝构造函数;而通过调用 move() 函数可以得到 demo 对象的右值形式,用其初始化 demo3 对象,编译器会优先调用移动构造函数。
  注意,调用拷贝构造函数,并不影响 demo 对象,但如果调用移动构造函数,由于函数内部会重置 demo.num 指针的指向为 NULL,所以程序中第 30 行代码会导致程序运行时发生错误。
  
  程序中分别构建了 first 和 second 这 2 个类,其中 second 类中包含一个 first 类对象。如果读者仔细观察不难发现,程序中使用了 2 此 move() 函数:
  程序第 31 行:由于 oth 为左值,如果想调用移动构造函数为 oth2 初始化,需先利用 move() 函数生成一个 oth 的右值版本;
  程序第 22 行:oth 对象内部还包含一个 first 类对象,对于 oth.fir 来说,其也是一个左值,所以在初始化 oth.fir 时,还需要再调用一次 move() 函数。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!