Á. *_*ton 1 c++ move-semantics c++11
标题几乎总结了我的问题.更详细:我知道当我在C++ 11中声明移动构造函数和移动赋值运算符时,我必须"使其他对象变量为零".但是,当我的变量不是一个array或一个简单int或double值,但它是一个更"复杂"的类型时,它是如何工作的?
在这个例子中,我有一个Shoplist带有vector成员变量的类.我是否必须vector在移动赋值运算符和构造函数中调用类的析构函数?或者是什么?
class Shoplist {
public:
Shoplist() :slist(0) {};
Shoplist(const Shoplist& other) :slist(other.slist) {};
Shoplist(Shoplist&& other) :slist(0) {
slist = other.slist;
other.slist.~vector();
}
Shoplist& operator=(const Shoplist& other);
Shoplist& operator=(Shoplist&& other);
~Shoplist() {};
private:
vector<Item> slist;
};
Shoplist& Shoplist::operator=(const Shoplist& other)
{
slist = other.slist;
return *this;
}
Shoplist& Shoplist::operator=(Shoplist&& other)
{
slist = other.slist;
other.slist.~vector();
return *this;
}
Run Code Online (Sandbox Code Playgroud)
无论std::vector为了正确移动需要做什么,都将由它自己的移动构造函数来处理.
因此,假设您想要移动该成员,只需直接使用它:
Shoplist(Shoplist&& other)
: slist(std::move(other.slist))
{}
Run Code Online (Sandbox Code Playgroud)
和
Shoplist& Shoplist::operator=(Shoplist&& other)
{
slist = std::move(other.slist);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以像AndyG所指出的那样,只是= default让编译器生成完全相同的移动ctor并为您移动赋值运算符.
请注意,明确地摧毁原件绝对是绝对错误的.超出范围时,该other成员将再次被销毁other.
编辑:我确实说过你想要移动会员,因为在某些情况下你可能不会.
一般来说,如果它们在逻辑上是类的一部分,那么你想要移动这样的数据成员,并且移动比复制要便宜得多.虽然std::vector移动比复制更便宜,但如果它拥有一些临时缓存或临时值,这在逻辑上不是对象的身份或价值的一部分,那么您可以合理地选择丢弃它.