18

概要

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

细节

考虑以下场景:

struct T { };
struct U { };

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

有没有办法既安全TU安全地移动建造?

4

3 回答 3

18

tl;博士:问题中的代码没问题。

上面的代码很好,因为std::move它本身实际上并没有other以任何方式改变,它只是进行了一次强制转换以other形成一个右值引用,以便调用 and 的移动构造函数TU不是它们的复制构造函数。

T(std::move(other))运行时,将T调用 的 move 构造函数(假设它有一个),并且Tinother将移动到Tin this。在运行之前,Uinother将被单独放置U(std::move(other))

请注意,这意味着当您的移动构造函数代码X运行时,您不能依赖TUin的成员/成员函数other,因为这些位other已经被移动了。


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

X(X&& other)
  : T(std::move(static_cast<T&>(other)))
  , U(std::move(static_cast<U&>(other)))
{
}

因为这个版本不依赖于X&&to T&&/的隐式向上转换U&&。依赖隐式向上转换可能是一个问题,因为T和/或U可能有一个T(X&&)构造函数或一个接受任何模板构造函数,它们中的任何一个都会被选中,而不是T(T&&)你真正想要调用的移动构造函数。

于 2012-04-11T22:13:59.990 回答
0

正如@je4d 的回答所解释的那样,问题中的代码很好。

你也可以这样写:

X(X&& other)
  : T(static_cast<T&&>(other))
  , U(static_cast<T&&>(other))
{
}

请参阅@jead 的答案评论以获取解释。

于 2021-12-07T15:26:00.403 回答
0

使用移动后,我可以在侧音构造函数主体中使用其他对象吗:

struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    member1 = other.member1; //something like. 

    }
};
于 2022-02-08T15:13:48.673 回答