10

aから移動-構築する場合b、それでも破壊する必要bがありますか、それともそうせずに逃げることができますか?

optional<T>この質問は、テンプレートの実装中に頭に浮かびました。抜粋:

~optional()
{
    if (initialized)
    {
        reinterpret_cast<T*>(data)->~T();
    }
}

optional(optional&& o) : initialized(o.initialized)
{
    if (initialized)
    {
        new(data) T(std::move(*o));   // move from o.data
        o.initialized = false;        // o.data won't be destructed anymore!
    }
}

もちろん、boolinitializedを、初期化、非初期化、および移動元を区別する3値の列挙に置き換えることもできます。これが厳密に必要かどうかを知りたいだけです。

4

3 に答える 3

14

はい、それでも破壊する必要がありbます。移動元オブジェクトは、有効な構築済みオブジェクトです。場合によっては、まだ廃棄する必要のあるリソースを保持していることもあります。あなたが示すようなジェネリックコードTでは、moveコンストラクターさえ持っていないかもしれません。この場合、代わりにコピーコンストラクタを呼び出すことができます。したがって、〜T()がノーオペレーションであり、省略できるとは絶対に想定できません。

于 2011-08-04T15:24:17.663 に答える
3

はい、あなたはまだそれらを破壊する必要があります。この欠陥を示す可能性のある設計の1つは、たとえば、あるオブジェクトが別のオブジェクトへのポインターのリストを保持するオブザーバーベースのパターンです。デストラクタを実行しなくてもポインタは削除されず、存在しなくなったオブジェクトにアクセスしようとするとコードがクラッシュします。

この例で行うのが簡単なのは、moved-fromオブジェクトでinitializedをfalseに設定しないことです。値は、移動された後も有効な状態であると定義されており、参照している右辺値のデストラクタは、それ以上の介入なしに値をクリーンアップします。

于 2011-08-04T15:21:23.213 に答える
2

私はあなたの質問に「いいえ」と答えたいのですが、それが正しい質問でさえあるかどうかはわかりません。次のことを考慮してください。

{  // start of scope
    T maybe_moved;
    if(some_condition) {
        T(std::move(maybe_moved));
    }
// end of scope
}

T::~T()明らかに、maybe_movedオブジェクトに対して1回だけ呼び出す必要があります。移動コンストラクターがそれを呼び出す場合、そのような無害なコードをどのように機能させるでしょうか?

于 2011-08-04T15:25:06.063 に答える