这是我的代码:
#include <iostream>
class carl{
public:
int x;
carl(int y):x(y){
}
carl(carl&& other)
{
std::cout<<" cons called?"<<std::endl;
this->x = other.x;
other.x = 0;
}
void operator=(carl&& other){
std::cout<<"operator called?"<<std::endl;
this->x = other.x;
other.x = 0;
}
};
void funct(carl&& get){
std::cout<<get.x<<std::endl;
}
int main(int argc, char** argv) {
carl c(2);
funct(std::move(c));
std::cout<<c.x<<std::endl;
return 0;
}
输出:
2
2
如果我记得,对于特殊成员函数有一个特殊的规则,声明如果一个类声明了一个移动构造函数/运算符,那么该类将不会自动生成复制运算符/构造函数。
根据我的例子,似乎没有调用移动运算符和构造函数,而是复制值。它应该排空c&#39; x
并执行cout
确认但没有发生这种情况。任何人都可以澄清我的代码发生了什么吗?
答案 0 :(得分:2)
您的代码中没有发生任何动作。 func
将引用作为参数,因此传递std::move(c)
只会绑定引用 - 不会发生复制或移动。关键的事实是std::move
不移动,它只返回指定对象的右值。如果您按值获取参数:
void func(carl get);
然后你将创建一个使用移动构造函数初始化的新对象(假设你将rvalue传递给func
)。
答案 1 :(得分:2)
对于你的例子,这里,
void funct(carl&& get) { std::cout<<get.x<<std::endl; }
提供与
完全相同的行为void funct(carl& get) { std::cout<<get.x<<std::endl; }
即:您传递对函数的引用。
只有当你将rvalue引用移动到新对象时,事情才会改变:
void funct(carl&& get)
{
auto my_carl = std::move(get);
std::cout<<my_carl.x<<std::endl;
}
然后编译器调用carl
的移动构造函数将内容移出对象而不是复制。