【发布时间】:2017-11-03 23:50:33
【问题描述】:
我一直难以理解 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 这不是这个的真正副本。这里发生的是最令人烦恼的解析,而不是复制省略。
-
@Angew 好电话。错过了。
-
@Angew 我实际上试图做的是通过其移动构造函数构造一个对象,当 NathanOliver 将我引导到另一个问题时,我真的认为这是重复的。在您指出之前,我什至没有注意到第 3 行的语句是函数签名。我也从未听说过最令人烦恼的解析,所以感谢您与我分享;我将阅读它以了解它是什么。
标签: c++ move-semantics rvalue-reference move-constructor most-vexing-parse