将对象作为函数的参数发送时移动语义
Move semantics when sending object as function's parameter
我正在使用移动构造函数和移动赋值,我偶然发现了这个问题。第一个代码:
#include <iostream>
#include <utility>
class Foo {
public:
Foo() {}
Foo(Foo&& other) {
value = std::move(other.value);
other.value = 1; //since it's int!
}
int value;
private:
Foo(const Foo& other);
};
void Bar(Foo&& x) {
std::cout << "# " << x.value << std::endl;
}
int main() {
Foo foo;
foo.value = 5;
Bar(std::move(foo));
std::cout << foo.value << std::endl;
return 0;
}
在我看来,当我使用:
Bar(std::move(foo));
程序应该将foo对象"移动"到使用Bar函数中的移动构造函数创建的临时对象。这样做会使 foo 对象的值等于零。不幸的是,它接缝了 Bar 函数中作为参数保存的对象是某种参考,因为它不会"移动"原始值,但使用 Bar 的参数我可以更改它。
有人介意解释我为什么我在控制台中看到:
#5
5
而不是
#5
0 //this should be done by move constructor?
右值引用是(惊喜:)确实是一个参考。
您可以从中移动,但std::move
不会移动。
因此,如果您不离开它,您将实际对 rvalue 对象进行操作(通过 rvalue 引用)。
通常的模式是
void foo(X&& x)
{
X mine(std::move(x));
// x will not be affected anymore
}
但是,当您这样做时
void foo(X&& x)
{
x.stuff();
x.setBooDitty(42);
}
实际上,X&& 只是充当传统的参考
当你写value = std::move(other.value);
时,你应该明白std::move
不会移动任何东西。它只是将其参数转换为右值引用,然后,如果左侧有一个移动构造函数/赋值运算符,则左侧处理它(以及如何实际移动对象)。对于普通旧类型 (POD),std::move
实际上不会执行任何操作,因此旧值保持不变。你没有"物理"移动任何东西。
比较这两个函数:
void Bar(Foo&& x) {
std::cout << "# " << x.value << std::endl;
}
与。
void Bar(Foo&& x) {
std::cout << "# " << x.value << std::endl;
Foo y=std::move(x);
}
两者都采用右值引用,但只有第二个调用移动构造函数。因此,第一个的输出是
# 5
5
而第二个的输出 - 因为foo
的值被改变 - 是:
# 5
1
演示
编辑:这是我前段时间遇到的一个问题。我的错误是假设创建右值引用直接调用移动构造函数的调用。但是,如前所述,std::move
在运行时不执行任何操作,它只是将类型更改为右值引用。仅当您将右值引用"移动"到另一个对象(如上所述)时,才会调用 move 构造函数。
Bar 函数不应引用&&
(此语法仅在移动构造函数声明/定义中有效):
void Bar(Foo x) { ... } // not "Foo&& x"
在函数栏中调用临时参数对象的移动构造函数:
Bar( std::move( x ) );
调用复制构造函数:
Bar( x );
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 移动语义和深层/浅层复制之间有什么关系?
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 在C++中使用移动语义的正确方法是什么?
- 移动语义 c++ 单链表
- C++:使用整数移动语义
- 当变量和参数名称匹配时,移动语义构造失败
- 在 C++11 中移动语义
- 方法冗余移动调用的移动语义
- 复制省略并在返回值中移动语义
- std::元组和移动语义
- 移动语义与返回shared_ptr?
- C++具有移动语义的可变参数工厂会导致运行时崩溃