18

あらすじ

クラスが多重継承を使用している場合、ムーブ コンストラクターを安全に設計するにはどうすればよいですか?

詳細

次のシナリオを検討してください。

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

4

3 に答える 3

18

tl;dr : 問題のコードは問題ありません。

上記のコードは問題ありstd::moveません。それ自体は実際にはまったく変更されないため、コピー コンストラクターの代わりに と の移動コンストラクターが呼び出されるように右辺値参照にotherキャストするだけです。otherTU

T(std::move(other))が実行されると、Tの move コンストラクターが呼び出され (存在する場合)、inTが inotherに移動さTthisます。が実行されるまで、Uインotherは放置されU(std::move(other))ます。

これは、移動コンストラクター コードが実行されるときに、およびXのメンバー/メンバー関数に依存できないことを意味することに注意してください。これらの部分は既に移動されているためです。TUotherother


補足として、次のように変更することで改善される可能性があります。

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

このバージョンは/X&&からの暗黙的なアップキャストに依存していないためです。暗黙的なアップキャストに依存することは問題になる可能性があります。これは、 and/orがコンストラクターまたは何でも受け入れるテンプレート コンストラクターを持っている可能性があり、実際に呼び出したい move コンストラクターの代わりにどちらかが選択される可能性があるためです。T&&U&&TUT(X&&)T(T&&)

于 2012-04-11T22:13:59.990 に答える