31

次のスニペットは、それ以外の方法で生成されたクラスのメソッドとコンストラクターをすべて定義解除するのに正しいですか?

struct Picture {

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no accidental construction, i.e. temporaries and the like
  Picture() = delete;

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;

  // no move
  Picture(Picture&&) = delete;

  // no move-assign
  Picture& operator=(Picture&&) = delete; // return type correct?
};

これにより、すべてのデフォルトのコンパイラ実装が削除され、デストラクタだけが残りますよね? それがなければ、クラスは(ほとんど)使用できないと思いますが、削除することもできますよね?

Picture&move-assignの戻り値の型はoperator=(Picture&&)正しいですか? Picture&&戻り値の型について書いた場合、違いはありますか?

4

2 に答える 2

27

Xeoの答えに加えて:

はい、すべて正しいです。必要に応じて、削除されたすべてのメンバーを削除できますが、削除されたコピー コンストラクターと削除されたコピー割り当ては同じ効果があります。

struct Picture {  // Also ok

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;
};

コピー コンストラクターの明示的な宣言は、既定のコンストラクター、ムーブ コンストラクター、およびムーブ代入メンバーの暗黙的な生成を禁止します。これらのメンバーを明示的に削除するかどうかは好みの問題です。一部の人は、おそらくそれを優れたドキュメントと見なすでしょう。他の人は、それが過度に冗長であると見なすかもしれません。

于 2011-04-16T15:32:16.073 に答える
3

私には問題ないようです。オブジェクトが右辺値参照から構築されている場合でも、の戻り値は通常の参照でoperator= なければなりません。*thisこれは、左辺値 ( ) を右辺値にコンパイルすることはできないためです。
そして、 non-const ごとにその右辺値参照を取る必要がありますPicture& operator=(Picture&&)。定数オブジェクトからどのように移動しますか? ;)

于 2011-04-16T14:23:24.000 に答える