次のスニペットは、クラスに対して生成されたすべてのメソッドとコンストラクターの定義を解除するのに正しいですか?
_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?
};
_
これにより、デフォルトのコンパイラ実装がすべて削除され、デストラクタだけが残ります。それがないと、クラスは(ほとんど)使用できなくなると思いますが、削除することもできますよね?
ムーブ代入operator=(Picture&&)
の戻り値の型_Picture&
_は正しいですか?戻り値の型に_Picture&&
_を記述した場合、違いはありますか?
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;
};
コピーコンストラクターの明示的な宣言は、デフォルトコンストラクター、ムーブコンストラクター、およびムーブ代入メンバーの暗黙的な生成を禁止します。これらのメンバーを明示的に削除するのは好みの問題です。おそらくそれを良いドキュメントと見なす人もいるでしょう。他の人はそれを過度に冗長であると見なすかもしれません。
私には問題ないようです。 _operator=
_ 必須の戻り値は、オブジェクトが右辺値参照から構築されている場合でも、通常の参照です。これは、左辺値(_*this
_)を右辺値にコンパイルするだけでは不十分だからです。
そして、非const Picture& operator=(Picture&&)
ごとにその右辺値参照を取得する必要があります。一定のオブジェクトからどのように移動しますか? ;)