1

ムーブ代入演算子では、std::moveまたはstd::swapを使用する必要がありますか?

やった:

void Swap(Image& Img) {/*Swap everything here*/}

Image& Image::operator = (const Image &Img)
{
    if (this != &Img) Img.Swap(*this); //Compiler error for copy assignment.. no match for swap taking const..
    return *this;
}

Image& Image::operator = (Image&& Img)
{
    Img.Swap(*this);
    return *this;
}

IとJの2つの画像があり、次のようになっていると仮定します。

I = std::move(J);

何が起こるかというと、IとJからのデータが交換されるため、JはIのピクセルを持ち、その逆も同様です。これは正常ですか?ムーブ代入は盗んで破壊することになっていると思いましたか?JをIに移動すると、Jの内容が取得され、Jが破棄されるようになりますか?しかし、それでも私はこれらの例をネット上で見ています

同じコードがmoveコンストラクターで機能しているのを見ることができますが、これは割り当てでどのように機能しますか?意味がないようです:S

std :: moveはmoveコンストラクターでも使用する必要がありますか?コンストラクターでstd::moveを使用すると、プログラムがクラッシュします。

Image::Image(Image&& Img) : Pixels(), Info(), /*Default everything*/
{
    this->Swap(Img);
    Img.Pixels.clear();
}

上記のコンストラクターは機能します。ただし、コンストラクターでstd :: moveを使用する場合:

Image::Image(Image&& Img) : Pixels(std::move(Img.Pixels)), Info(std::move(Img.Info)), /*move everything*/
{
    //Do I need to set Img's values to default? Or does std::move do that?
}

移動されたオブジェクトを使用しようとすると、プログラムがクラッシュします。

Image I = Image("C:/Image.bmp");
Image J = std::move(I);
I.Draw(...); //Crashes program if using std::move. If using the swap version of the constructor, it works. I assume it's because swap version defaults everything.
4

1 に答える 1

3

効率的なスワッピングと移動の構築をサポートしている場合は、値ごとに1つの代入演算子のみを使用する必要があります。

Foo & operator=(Foo rhs) { rhs.swap(*this); }

ユーザーがconst-referenceを渡した場合は、とにかくコピーを作成する必要があります。ユーザーが右辺値を渡す場合、ローカル変数の作成rhsは安価です。

つまり、コピー/ムーブコンストラクター、コピー/ムーブ代入、スワップの3つのうち、2つだけを深く実装する必要があります(これら2つのうちの1つがコンストラクターである必要があります)。

于 2013-03-11T03:42:46.857 に答える