2

移動コンストラクターを使用または作成する正しい方法は何ですか?

次に例を示します。

class Example
{
public:
    Example( int && p_Number,
             bool && p_YesNo,
             std::string && p_String ) : // Error here
             Number( p_Number ),
             YesNo( p_YesNo ),
             String( p_String )
    {
    };

private:
    int Number;
    bool YesNo;
    std::string String;
    std::vector< unsigned char > Vector;
};

void ShowExample( void )
{
    Example ExampleA( 2013,
                      true,
                      "HelloWorld" // Why won't it work?
                      );
};

コメントでエラーを表示しました。

編集: *さて、私が持っているのはムーブ コンストラクターではないことがわかりました。それで、私はそれを書くことができますか?*

4

2 に答える 2

11

まず第一に、そのクラスのムーブ コンストラクターを記述する理由はありません。コンパイラが生成したものは問題なく動作します。しかし、それを書くとしたら、次のようになります。

Example(Example && rhs)
    :Number(rhs.Number)
    ,YesNo(rhs.YesNo)
    ,String(std::move(rhs.String))
    ,Vector(std::move(rhs.Vector))
{}

std::move必要に応じて、一貫性を保つためにintとを呼び出すことboolができますが、それからは何も得られません。

その他のコンストラクターの場合、すべての引数を使用して、最も簡単なことは次のとおりです。

Example(int p_Number, bool p_YesNo, std::string p_String)
    :Number(p_Number)
    ,YesNo(p_YesNo)
    ,String(std::move(p_String))
{}

以下のあなたのコメントに応えて:

唯一のコンストラクター引数と同じ型の R 値を使用してオブジェクトを構築しようとするたびに、ムーブ コンストラクターが呼び出されます。たとえば、オブジェクトが関数から値によって返される場合、それは R 値ですが、多くの場合、その場合、コピーと移動は完全にスキップされます。R 値を作成できるケースはstd::move、L 値を呼び出すことです。例えば:

Example ex1(7, true, "Cheese"); // ex1 is an L-value
Example ex2(std::move(ex1));    // moves constructs ex2 with ex1
于 2013-03-02T00:44:40.227 に答える
5

移動コンストラクターは、同じ型の別のオブジェクトへの右辺値参照を受け取り、他のオブジェクトのリソースを新しいオブジェクトに移動します。次に例を示します。

Example(Example && other) :
    Number(other.Number),             // no point in moving primitive types
    YesNo(other.YesNo),
    String(std::move(other.String)),  // move allocated memory etc. from complex types
    Vector(std::move(other.Vector))
{}

ただし、クラス自体がリソースを管理していない限り、これを記述しても意味がありません。暗黙の移動コンストラクターは、私が記述したものとまったく同じことを行います。

于 2013-03-02T00:45:41.597 に答える