C++ 将对象的值移动到另一个对象,但避免复制

C++ 将对象的值移动到另一个对象,但避免复制,c++,c++11,C++,C++11,有一种情况是,当我通过回调从API获得应答时,我需要将应答中的对象移动到我的类成员变量以继续处理。以下准则能否达到目标: class Obj { public: Obj (unit32_t& x, std::string& x, int& data) {} ... lot of variable .. no pointers }; class A { public: A(Obj& r):pvtmemVarTyOfObj(0,"",0) {} private:

有一种情况是,当我通过回调从API获得应答时,我需要将应答中的对象移动到我的类成员变量以继续处理。以下准则能否达到目标:

class Obj {
public:
 Obj (unit32_t& x, std::string& x, int& data)
{}
... lot of variable .. no pointers
};
class A
{
public:
 A(Obj& r):pvtmemVarTyOfObj(0,"",0) {}
 private:
 Obj pvtmemVarTyOfObj ;
};

void A::GetResponse(Obj&& resp)
{
  //pvtmemVarTyOfObj = std::forward<Obj>(std::move(resp));
   pvtmemVarTyOfObj = std::move(resp);

}
类Obj{
公众:
Obj(单元32_t&x,标准::字符串和x,整数和数据)
{}
…很多变量..没有指针
};
甲级
{
公众:
A(Obj&r):pvtmemVarTyOfObj(0,“,0){}
私人:
Obj pvtmemVarTyOfObj;
};
void A::GetResponse(Obj&&resp)
{
//pvtmemVarTyOfObj=std::forward(std::move(resp));
pvtmemVarTyOfObj=std::move(resp);
}
这段代码实际上会将resp移动到pvtmemVarTyOfObj成员变量吗?只是为了确保不进行复制,因为这将导致巨大的处理成本?

只需在此处使用
std::move(resp)
。您肯定知道
resp
是一个右值引用,因此您总是希望移动

如果
Obj
是一个模板参数,则需要使用
std::forward(resp)
。因为在这种情况下,
Obj&
将是一个通用的参考,它可以是一个右值左值参考,
std::forward
推断是否可以移动
resp


最终是执行复制还是移动取决于pvtmemVarTyOfObj类的赋值运算符。如果它只包含普通数据且没有分配的资源(例如通过指针),则move不能提供任何好处。

move构造函数和move assignment操作符只能执行它们所做的操作 编程来做的,由你来编程。从技术上讲,它们可以设计为 做任何事,但那是不可取的。
相反,它们的设计应该使目标对象与目标对象无法区分 源对象,同时使源对象保持有效状态。
如果您自己不提供移动操作,将通过以下方式合成一个移动操作 会员明智之举。
移动基本类型,如
int
,只需复制即可。
移动许多库类型,例如
std::vector
std::string
std::unique_ptr
,由库实现者设计用于传输 资源的所有权,如内存。
这意味着,对于堆栈分配的POD,无法避免 一份。如果操作对性能至关重要,并且拷贝是不可接受的, 例如,解决方案可能是首先不使用堆栈分配的POD 将对象粘贴在
std::unique\u ptr
中的示例
另一种选择可能是只拥有目标对象,并让其他人“访问”
通过指针或引用创建该对象。

您不应该使用
移动
向前
。使用一个或另一个。谢谢-我应该删除move或forward以帮助更好地处理-注意我的构造函数作为左值接收-这会是一个问题吗?这取决于您。您是否理解
前进
移动
之间的区别?您必须决定是无条件移动还是只移动右值。编辑:我甚至没有注意到,Obj不是一个模板类型,所以它不是一个通用的参考。。。在本例中:move.向我们展示
Obj
的定义可能有助于“Moving”不会实际移动任何东西。考虑“转移对象(间接持有)资源的所有权”,而不是“更改对象的位置”。谢谢,但它不会复制“=”运算符的原因吗?这取决于PvtMemVartyOfBj的类。它有超载吗?或者仅仅是?它没有它们,但编译器会在它们未定义时调用或执行任何代价高昂的复制操作吗?如果没有关于PVTMemVartyOfBj类的更多信息,就说不出来。如果您不需要复制构造函数,并且担心它会被调用,请考虑删除它