6

クラスのひし形の階層があり、デフォルト コンストラクターもコピー コンストラクターもありません。私が持っている2つのコンストラクターは、オブジェクトへの左辺値参照を取る「移動」のものと別のものです。

struct base {
    base(base&&) = default;
    base(member_type&& m): member_(std::move(m)) {}
    member_type member_;
};

struct virt_1: virtual base {
    virt_1(virt_1&& rhs): base(std::move(rhs)) {}
    virt_1(member_type&& m): base(std::move(m)) {}
};

struct virt_2: virtual base {
    virt_2(virt_2&& rhs): base(std::move(rhs)) {}
    virt_2(member_type&& m): base(std::move(m)) {}
};

struct concrete: virt_1, virt_2 {
    concrete(concrete&& rhs) // ???
};

ひし形の階層を使用しないことに加えて、具象クラスの移動コンストラクターを実装することは可能ですか?

ありがとう!

4

2 に答える 2

9

コンパイラに実装を提供するように依頼することの何が問題になっていますか?

concrete(concrete&&) = default;

virt_1コンストラクターとvirt_2移動コンストラクターもデフォルトとして定義します。

本当にしたい場合は、次のように書くことができます。

concrete(concrete&& rhs)
: base(std::move(rhs)), virt_1(std::move(rhs)), virt_2(std::move(rhs))
{ }

または、タイピングが本当に好きな場合:

    concrete(concrete&& rhs)
    : base(static_cast<base&&>(rhs)),
      virt_1(static_cast<virt_1&&>(rhs)),
      virt_2(static_cast<virt_2&&>(rhs))
    { }

virt_1およびベースのイニシャライザはvirt_2、コンストラクタを呼び出すだけでbaseあり、仮想ベースであるconcreteため、呼び出されたときにそれを実行しないため、役に立ちませんが、コンストラクタの選択により、それらをデフォルトで構築することはできず、必要です何もしないにもかかわらず、右辺値で初期化します。

于 2013-07-08T11:50:48.397 に答える
1

もちろん。階層内のどこかにベースを持つコンストラクターは、virtualそのベースを初期化する責任があります。基本的virtualに、階層内のベースの下にあるすべてのクラスは、ベースを初期化する権限を継承します。

この場合、デフォルトの移動コンストラクターは正しいことを行う必要があります。concrete : private virtual base何が起こっているのかを明確にするために指定することもお勧めします。

これが動作するデモです。

于 2013-07-08T11:39:17.523 に答える