当类使用多重继承时,如何安全地设计移动构造函数?
考虑以下情况:
struct T { };
struct U { };
struct X : public T, public U
{
X(X&& other)
: T(std::move(other))
, U(std::move(other)) // already moved?!
{
}
};
有没有办法安全地移动构建T
和U
?
答案 0 :(得分:13)
tl; dr :问题中的代码没问题。
上面的代码很好,因为std::move
本身并没有以任何方式实际更改other
,它只是进行强制转换以使other
成为右值引用,以便调用T
和U
的移动构造函数而不是它们的复制构造函数。
运行T(std::move(other))
时,将调用T
移动构造函数(假设它有一个),T
中的other
将被移动到T
中的this
。 U
中的other
将一直保留,直到U(std::move(other))
运行。
请注意,这意味着当X
的移动构造函数代码运行时,您不能依赖T
中U
和other
的成员/成员函数,那些other
的位已经被移动了。
作为旁注,可以通过更改为:
来改进X(X&& other)
: T(std::move(static_cast<T&>(other)))
, U(std::move(static_cast<U&>(other)))
{
}
因为此版本不依赖于从X&&
到T&&
/ U&&
的隐式向上广播。依赖隐式上传可能是一个问题,因为T
和/或U
可能有一个T(X&&)
构造函数或一个accept-anything模板构造函数,其中任何一个都会被选中而不是{ {1}}移动您真正想要调用的构造函数。