12

おもちゃクラスのムーブ コンストラクターの実装中に、次のパターンに気付きました。

array2D(array2D&& that)
{
    data_ = that.data_;
    that.data_ = 0;

    height_ = that.height_;
    that.height_ = 0;

    width_ = that.width_;
    that.width_ = 0;

    size_ = that.size_;
    that.size_ = 0;
}

パターンは明らかに次のとおりです。

    member = that.member;
    that.member = 0;

そこで、スティーリングの冗長性を減らし、エラーを起こしにくくするプリプロセッサ マクロを作成しました。

#define STEAL(member) member = that.member; that.member = 0;

実装は次のようになります。

array2D(array2D&& that)
{
    STEAL(data_);
    STEAL(height_);
    STEAL(width_);
    STEAL(size_);
}

これには欠点がありますか?プリプロセッサを必要としないよりクリーンなソリューションはありますか?

4

3 に答える 3

12

推奨されるパターンは次のとおりです。

array2D(array2D&& that)
    : data_(std::move(that.data_)),
      height_(std::move(that.height_)),
      width_(std::move(that.width_)),
      size_(std::move(that.size_))
{
    that.data_ = 0;
    that.height_ = 0;
    that.width_ = 0;
    that.size_ = 0;
}

当然、データ メンバーがスカラー型の場合std::moveは必要ありません。ただし、このパターンをコピーする場合は、メンバー データがスカラーでない場合に が忘れられないmoveように、とにかくを含めると便利です。std::move

また、メンバー データに実際の移動コンストラクターがある場合は、本体を単純に省略できます。

array2D(array2D&& that)
    : data_(std::move(that.data_)),
      height_(std::move(that.height_)),
      width_(std::move(that.width_)),
      size_(std::move(that.size_))
{
}

また、移動コンストラクターを持たないが、リソースのないデフォルトの構築状態を持つ型に一般化する場合は、次のことができます。

array2D(array2D&& that)
    : data_(std::move(that.data_)),
      height_(std::move(that.height_)),
      width_(std::move(that.width_)),
      size_(std::move(that.size_))
{
    that.data_ = Data();
    that.height_ = Height();
    that.width_ = Width();
    that.size_ = Size();
}

array2Dクラス定義でデータ メンバーとして宣言されているのと同じ順序でこれらのステートメントを並べることをお勧めします。そして、本体の初期化子リストの繰り返しに問題はありません。これ必要な第 2 のステップです。敷物の下を掃除する必要はありません。

于 2011-06-27T12:23:31.240 に答える
9

使ってみませんかtemplate

template<typename T> inline
void MOVE(T &dst, T &src)
{
  dst = src;
  src = 0;
}

使用法:

MOVE(data_, that.data_);

@Fred、あなたのコメントから、データメンバーについて2回言及することを避けたい場合は、次のようにします。

#define STEAL(X) MOVE(X, that.X)

使用法:

STEAL(data_);
于 2011-06-27T11:51:38.190 に答える
5

独自のメンバーをデフォルトに初期化してから、swap

array2D(array2D&& that)
{
    data_ = 0;    
    height_ = 0;    
    width_ = 0;    
    size_ = 0;

    this->swap(that);
}

さらにクリーン(コンパイラがサポートしている場合)

array2D(array2D&& that)
: array2D() {
    this->swap(that);
}
于 2011-06-27T11:55:39.943 に答える