我一直有困难在C++中理解移动构造函数。我用默认构造函数,复制构造函数,移动构造函数和析构函数做了一个简单的类。另外,我定义了一个带有两个重载的函数,一个接受对该类的引用,另一个接受对该类的右值引用。我的测试代码如下。与移动构造函数混淆:无法调用移动构造函数
#include <iostream>
class c {
public:
c() {
std::cout << "default constructor" << std::endl;
}
c(const c& s) {
std::cout << "copy constructor" << std::endl;
}
c(c&& s) {
std::cout << "move constructor" << std::endl;
}
~c() {
std::cout << "destructor" << std::endl;
}
};
void f(c& s) {
std::cout << "passed by reference" << std::endl;
}
void f(c&& s) {
std::cout << "passed by rvalue reference" << std::endl;
}
int main() {
c s1; // line 1
std::cout << "\n";
c s2(s1); // line 2
std::cout << "\n";
c s3(c()); // line 3
std::cout << "\n";
f(s1); // line 4
std::cout << "\n";
f(c()); // line 5
getchar();
return 0;
}
我得到的输出不是我期待的。以下是我从这段代码中得到的输出。
default constructor
copy constructor
passed by reference
default constructor
passed by rvalue reference
destructor
我可以理解除line 3
之外的所有行的输出。在line 3
,这是c s3(c());
,c()
是一个右值,所以我认为s3
将移动构建。但是输出结果并不表明它是构建的。在line 5
上,我正在做同样的事情并将rvalue
传递给函数f()
,它确实调用接受rvalue
引用的过载。我很困惑,并希望有关于此的任何信息。
编辑:我可以调用移动构造函数,如果我c s3(std::move(c()));
但我没有传递一个右值到s3?为什么我需要std::move
?
@NathanOliver这不是真的这一块的副本。这里发生的事情是最痛苦的解析,而不是复制elision。 – Angew
@Angew好的电话。错过了。 – NathanOliver
@Angew我实际上想要做的是通过它的移动构造函数构造一个对象,当NathanOliver指示我去处理另一个问题时,我真的认为这是重复的。我甚至没有注意到第3行的声明是一个函数签名,直到您指出。我从来没有听说过最棘手的解析,所以谢谢你与我分享;我会阅读它来了解它是什么。 – Deniz