可能已经提出并已经回答过了,但我不知道该搜索什么。
如果数据成员定义了移动赋值运算符,可以将移动语义用于非指针数据成员吗?
假设我有一个类M
,它定义M::operator=(M&&)
,如下所示:
template <class T>
class M
{
public:
M()
{
mem_M = new T;
}
M& operator=(M&& src)
{
if (this != &src)
{
mem_M = src.mem_M;
src.mem_M = nullptr;
}
return *this;
}
private:
T* mem_M;
};
现在显然我可以像这样使用C<T>
类,使用一个不使用T
移动赋值运算符的移动构造函数:
template <class T>
class C
{
public:
C ()
{
mem_C = new T;
}
C (C&& rhs)
{
mem_C = rhs.mem_C;
rhs.mem_C = nullptr;
}
private:
T* mem_C;
};
但是,如果我希望C<T>::mem_C
不是指针而是普通成员,我将如何在移动函数中处理C<T>::mem_C
?我当然可以调用移动赋值运算符T::operator=(T&&)
将字段mem_C
从一个实例移动到另一个实例,但是如何正确重置传递给C
的{{1}}实例}?
这对我来说至少看错了:
C<T>::C(C&&)
那么,在移动函数中重置非指针数据成员的标准兼容方法是什么?
答案 0 :(得分:3)
包含类型的移动赋值/构造函数必须将对象保留在&#34;可接受的&#34;无论对于那种类型,这意味着什么。移动类型之外的任何内容都不应该对维护对象的状态负责。
此外,您要确保在父移动构造函数中调用包含类型的移动构造函数,而不是包含类型的移动您在示例中分配:
// move constructor calls move constructor of contained elements
C (C<T>&& rhs) : mem_c(std::move(rhs.mem_c))
{
// anything in here is using already-constructed data members
}
// move assignment calls move assignment of contained elements
C & operator=(C<T>&& rhs) {
mem_c = std::move(rhs.mem_c);
}