我有一个关于移动语义的一般性问题。昨天我只是在这个主题上做了一些尝试。在这里我添加了复制和移动构造函数操作符,它们只会记录到控制台:
#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操作符应该执行。这两个案例之间有什么区别?
3条答案
按热度按时间hvvq6cgz1#
但是为什么没有调用Test的移动构造函数操作符呢?
因为你一直通过对右值的引用对同一个对象进行操作。没有新的对象被构造,因此不需要构造函数。
你可以继续向下传递这个引用,就像你可以处理一个常规引用或者一个对const的引用一样--引用的本质是它们不是对象。
在第二个示例中,函数的参数是一个值,为了构造该值,需要激发第二个构造函数。
rjee0c152#
首先,你传递了一个引用,因此,不需要创建新的对象。
bqjvbblv3#
在void showMe(Test test)中,形式参数期望通过值传递,因此调用了Move Constructed\(通过值传递意味着将参数复制到函数中。这将调用移动构造函数)。在第二种情况下,void showMe(Test&& test)形式参数期望通过引用传递,因此不会创建新对象,也不会调用构造函数