移动构造函数和多重继承

mav*_*vam 15 c++ multiple-inheritance move-constructor move-semantics c++11

概要

当类使用多重继承时,如何安全地设计移动构造函数?

细节

请考虑以下情形:

struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

有没有办法移动 - 构建TU安全?

je4*_*e4d 15

tl; dr:问题中的代码没问题.

上面的代码很好,因为std::move它本身实际上并没有other以任何方式改变,它只是做一个other强制转换为rvalue引用,以便调用T和移动构造函数U而不是它们的复制构造函数.

T(std::move(other))运行,T此举构造函数将被调用(假设它有一个),并且Tother将被移动到Tthis.在Uother,直到将被单独留在家中U(std::move(other))运行.

请注意,这意味着,当你的移动构造函数的代码X运行时,你不能依靠的会员/会员功能T,并Uother,为那些位other将已经被移动.


作为旁注,可以通过更改为:

X(X&& other)
  : T(std::move(static_cast<T&>(other)))
  , U(std::move(static_cast<U&>(other)))
{
}
Run Code Online (Sandbox Code Playgroud)

因为这个版本不依赖于隐式上溯造型从X&&T&&/ U&&.依赖隐式upcast可能是一个问题,因为T和/或U可能有一个T(X&&)构造函数或一个accept-anything模板构造函数,其中任何一个都将被选中而不是T(T&&)你真正想要调用的移动构造函数.

  • 为什么不是 `T(static_cast&lt;T&amp;&amp;&gt;(other))` 而不是 `T(std::move(static_cast&lt;T&amp;&gt;(other)))` (对于 `U` 也是如此)? (3认同)
  • 在这个例子中没有模板,如果有的话你可能想要`std :: forward`而不是`std :: move`.我认为在这里使用`move`会让事情变得混乱,但是我看到了你所得到的东西.: - ] (3认同)