c++ 移动语义和std::move

zd287kbt  于 2022-11-19  发布在  其他
关注(0)|答案(3)|浏览(235)

我有一个关于移动语义的一般性问题。昨天我只是在这个主题上做了一些尝试。在这里我添加了复制和移动构造函数操作符,它们只会记录到控制台:

#include <iostream>

class Test {    
public:
  const char* value = "HI";
  Test(){
     std::cout << "Default Constructed\n";
  }
  Test(Test &&source) { 
     std::cout << "Move Constructed\n";
  }
  Test(const Test &source) {
     std::cout << "Copy Constructed\n";
  }
};

现在当我打电话

void showMe(Test&& test) {
  std::cout << test.value;
}

int main() {
  Test test1;
  // Test test2{test1};
  showMe(std::move(test1));

  return 0;
}

控制台注销:
〉默认构造
〉HI
这对我来说很清楚,因为我们只是将所有权转移到showMe。但是为什么没有调用Test的move构造函数操作符呢?
但是现在,如果我把showMe函数改为

void showMe(Test test) {
  std::cout << test.value;
}

控制台显示:
〉默认构造
〉移动已构建
〉HI
所以我的问题是,为什么Move构造函数操作符没有在第一个案例中执行,而是在第二个案例中执行?我通常认为在第一个案例中,Test的move操作符应该执行。这两个案例之间有什么区别?

hvvq6cgz

hvvq6cgz1#

但是为什么没有调用Test的移动构造函数操作符呢?
因为你一直通过对右值的引用对同一个对象进行操作。没有新的对象被构造,因此不需要构造函数。
你可以继续向下传递这个引用,就像你可以处理一个常规引用或者一个对const的引用一样--引用的本质是它们不是对象。
在第二个示例中,函数的参数是一个值,为了构造该值,需要激发第二个构造函数。

rjee0c15

rjee0c152#

首先,你传递了一个引用,因此,不需要创建新的对象。

bqjvbblv

bqjvbblv3#

在void showMe(Test test)中,形式参数期望通过值传递,因此调用了Move Constructed\(通过值传递意味着将参数复制到函数中。这将调用移动构造函数)。在第二种情况下,void showMe(Test&& test)形式参数期望通过引用传递,因此不会创建新对象,也不会调用构造函数

相关问题