标题几乎总结了我的问题.更详细:我知道当我在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- 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; }
Useless.. 5
无论std::vector
为了正确移动需要做什么,都将由它自己的移动构造函数来处理.
因此,假设您想要移动该成员,只需直接使用它:
Shoplist(Shoplist&& other) : slist(std::move(other.slist)) {}
和
Shoplist& Shoplist::operator=(Shoplist&& other) { slist = std::move(other.slist); return *this; }
在这种情况下,您可以像AndyG所指出的那样,只是= default
让编译器生成完全相同的移动ctor并为您移动赋值运算符.
请注意,明确地摧毁原件绝对是绝对错误的.超出范围时,该other
成员将再次被销毁other
.
编辑:我确实说过你想要移动会员,因为在某些情况下你可能不会.
一般来说,如果它们在逻辑上是类的一部分,那么你想要移动这样的数据成员,并且移动比复制要便宜得多.虽然std::vector
移动比复制更便宜,但如果它拥有一些临时缓存或临时值,这在逻辑上不是对象的身份或价值的一部分,那么您可以合理地选择丢弃它.
无论std::vector
为了正确移动需要做什么,都将由它自己的移动构造函数来处理.
因此,假设您想要移动该成员,只需直接使用它:
Shoplist(Shoplist&& other) : slist(std::move(other.slist)) {}
和
Shoplist& Shoplist::operator=(Shoplist&& other) { slist = std::move(other.slist); return *this; }
在这种情况下,您可以像AndyG所指出的那样,只是= default
让编译器生成完全相同的移动ctor并为您移动赋值运算符.
请注意,明确地摧毁原件绝对是绝对错误的.超出范围时,该other
成员将再次被销毁other
.
编辑:我确实说过你想要移动会员,因为在某些情况下你可能不会.
一般来说,如果它们在逻辑上是类的一部分,那么你想要移动这样的数据成员,并且移动比复制要便宜得多.虽然std::vector
移动比复制更便宜,但如果它拥有一些临时缓存或临时值,这在逻辑上不是对象的身份或价值的一部分,那么您可以合理地选择丢弃它.