我在使用C +中的理解+使用移动语义时遇到了困难。我有一个对象Variable
实现移动构造函数和移动赋值,但没有复制构造函数和赋值。通常复制Variable
是没有意义的,我想禁止明确复制。
class Variable {
public:
// ctod/dtor things
Variable(Variable&&);
Variable& operator =(Variable&&);
// ...
};
问题是从函数返回Variable
的正确方法是什么?
Variable& UserObject::giveMeYourVariable() {
// Calculate parameters
Variable v(/* Some parameters */);
return v; // <=== warning: reference to local variable 'v' returned
}
在另一段代码中:
UserObject x* = new UserObject;
Variable v = std::move(x->giveMeYourVariable())
上面的代码编译时没有错误,但是有关返回对局部变量的引用的警告。此代码是否泄漏内存或导致未定义的行为或返回已删除的引用?怎么了?
更新
初始化引用类型时(在解析器生成器生成的代码内),按值返回会导致错误:
Variable& tmp (this->a_function()); <<== error
错误说:
error: invalid initialization of non-const reference of type 'Variable&' \\
from an rvalue of type 'Variable'
答案 0 :(得分:4)
您的程序会调用未定义的行为
正如编译器已经告诉你的那样,Variable
对象的生命周期仅限于函数调用,并且在调用后返回的引用不再有效。
您只需按值返回Variable
对象
Variable UserObject::giveMeYourVariable() {
并愉快地移动它。
答案 1 :(得分:-2)
您应该移动两次并按值返回Variable对象:
#include <utility>
class Variable {
public:
// ctod/dtor things
Variable() {}
Variable(Variable&&) {}
Variable& operator =(Variable&&) {return *this;}
// ...
};
Variable foo() {
Variable v;
return std::move(v);
}
int main() {
Variable v = std::move(foo());
return 0;
}
std :: move只是将类型从Variable转换为Variable&amp;&amp;,它允许用移动语义调用构造函数
这样:
第一个std :: move允许创建返回的临时对象
第二个std :: mode允许创建Variable v