八葉の日記

日々、感じたことをまとめる場として利用する

C++ Core Guidelines C.21

C++ Core Guidelinesの自分用翻訳


C.21: If you define or =delete any copy, move, or destructor function, define or =delete them all

Reason

The semantics of copy, move, and destruction are closely related, so if one needs to be declared, the odds are that others need consideration too.
コピー、移動、破壊のセマンティクスは密接に関連しているので、1つを宣言する必要がある場合、他のものも考慮する必要がある確率が高いです。


コピー/移動/デストラクタ関数のいずれかを宣言します。たとえ `=default` や `=delete` であっても、コピー/移動/デストラクタ関数を宣言すると、暗黙のうちに としてでも、コピー/移動/デストラクタ関数を宣言すると、移動コンストラクタと移動代入演算子の暗黙の宣言が抑制されます。
移動コンストラクタや移動代入演算子は、たとえ を宣言すると、暗黙のうちに生成されたコピー コンストラクタや や暗黙のうちに生成されるコピー代入演算子は削除されたものとして定義されます。
したがって、これらのいずれかが宣言されると同時に、他のものもすべて宣言して、すべての移動候補をより高価なコピーに変えてしまうような好ましくない影響を避けるべきです。をより高価なコピーに変えてしまったり、 クラスを移動専用にしてしまったりするような好ましくない効果を避けるために、 他のものもすべて宣言しておくべきです。

Example, bad

struct M2 {   // bad: incomplete set of copy/move/destructor operations
 public:
        // ...
        // ... no copy or move operations ...
        ~M2() { delete[] rep; }
 private:
        pair<int, int>* rep;  // zero-terminated set of pairs
};

void use()
{
    M2 x;
    M2 y;
    // ...
    x = y;   // the default assignment
    // ...
 }

デストラクタに「特別な注意」が必要だったことを考えると(ここでは、deallocateする)、暗黙的に定義されたコピーとムーブの代入演算子が正しくなる可能性は低い(ここでは、double deletionを得ることになる)。