0

Move コンストラクターの例を示す Web サイトから取得した配列クラスがあります。しかし、サンプルプログラムでこの移動コンストラクターをどのように実装しますか? 関数の定義は理解できた気がしますが、プログラムでこれをどのように利用するのかわかりません。

class ArrayWrapper
{
public:
    // default constructor produces a moderately sized array
    ArrayWrapper ()
        : _p_vals( new int[ 64 ] )
        , _size( 64 )
    {}

    ArrayWrapper (int n)
        : _p_vals( new int[ n ] )
        , _size( n )
    {}

    // move constructor, how does this come in handy?
    ArrayWrapper (ArrayWrapper&& other)
        : _p_vals( other._p_vals  )
        , _size( other._size )
    {
        other._p_vals = NULL;
    }

    // copy constructor
    ArrayWrapper (const ArrayWrapper& other)
        : _p_vals( new int[ other._size  ] )
        , _size( other._size )
    {
        for ( int i = 0; i < _size; ++i )
        {
            _p_vals[ i ] = other._p_vals[ i ];
        }
    }
    ~ArrayWrapper ()
    {
        delete [] _p_vals;
    }

private:
    int *_p_vals;
    int _size;
};
4

2 に答える 2

2

しかし、サンプルプログラムでこの移動コンストラクターをどのように実装しますか?

あなたが持っているコードはすでにそれを示していると思います。

関数の定義は理解できた気がしますが、プログラムでこれをどのように利用するのかわかりません。

移動をトリガーするには、いくつかの方法のいずれかを使用するだけです。例えば:

ArrayWrapper aw;
ArrayWrapper aw2 = std::move(aw);

あるいは:

ArrayWrapper foo()
{
    ArrayWrapper aw;
    //...
    return aw;
}

// ...

ArrayWrapper aw2 = foo();

この最後のケースでは、コンパイラは移動コンストラクタへの呼び出しを無視する可能性が高いことに注意してください。

于 2013-05-13T23:48:42.983 に答える
1

コピー コンストラクターと同じ状況で使用されますが、コピー元の式が右辺値である場合にのみ使用されます。通常、右辺値は一時オブジェクトを参照します。たとえば、 by 値fooを返す関数ArrayWrapperがある場合、その関数を呼び出す式は右辺値になります。

ArrayWrapper aw = foo();

ここで、ArrayWrapperオブジェクトは によって返された一時オブジェクトから構築されfooます。右辺値参照引数が右辺値式にバインドされるため、ムーブ コンストラクター オーバーロードが選択されます。

通常、移動コンストラクターは、移動元のオブジェクトを有効だが不確定な状態のままにします。

于 2013-05-13T23:49:35.370 に答える