[Effective C++] Ch2. 作成者、消灭者、代入演算子


Item 5. C++がこっそり作成して呼び出す関数に注目しましょう。

class empty {};
上記の空のクラスが作成されている場合は、コンパイラはデフォルトジェネレータ、レプリケーション作成者、レプリケーション代入演算子、および消滅者を自動的に暗黙的に作成することを確認します.

Item 6. コンパイラで生成された関数が必要ない場合は、それらを完全に無効にします。


クラスにレプリケーション作成者またはレプリケーション代入演算子が宣言されていない場合、コンパイラは自動的に作成され、共通メンバーになります.
コンパイラが自動的に機能を提供できない場合は、対応するメンバー関数をprivateとして宣言し、実装しないように保持するだけです.
コードに実装されていない関数を使用しようとすると、リンクエラーが発生し、無効になる可能性があります.

Item 7. 多形性を持つベースクラスでは、消滅者を仮想消滅者として宣言する必要があります。


複数のタイプのベースクラスの場合、仮想消滅者を宣言する必要があります.
派生クラスで定義されたデータ・メンバーは消えません.
しかし、いずれの場合も、消滅者をすべてvirtualと宣言することはできない.
仮想破棄器を宣言するとvptr(virtual table pointer)が生成され、vtbl(virtualtable)に登録され、vptrはクラスのサイズを大きくします.
この場合、Cなど他の言語で宣言された同じデータ構造とは互換性がありません
クラスに少なくとも1つの仮想関数が含まれている場合にのみ、仮想破棄を宣言します.

Item 8. 例外を消滅させない者


アクションによって例外が発生し、失敗する可能性があり、例外を処理する必要がある場合は、消滅者ではなく別の関数で処理する必要があります.

Item 9. オブジェクトの作成と破棄中に仮想関数を呼び出さないでください。


デフォルトクラス作成者は派生クラス作成者の前に実行されるため、デフォルトクラス作成者の実行時に派生クラスデータメンバーは初期化されていません.
ベースクラス作成者から偶然呼び出された仮想関数が派生クラスに降格した場合、派生クラスのデータ・メンバーは初期化されていないため、未定義の操作を行います.

Item 10. 代入演算子*はthisの参照を返します

int x, y, z;
x = y = z = 15;
上のコードを解くと,15はzに置き換えられ,更新されたzはyに置き換えられ,再更新されたyはxに置き換えられる.
この実施は慣例である

Item 11. operator=では、自分への代入処理を見逃さない


operator=実装時に特定のオブジェクトが自身に置き換えられた場合を正しく処理する必要がある
ソースオブジェクトとコピー先オブジェクトのアドレスを比較したり、コピー後に置換を使用したりできます.
しかし、番組の中でどれだけの自己代入が起こるのだろうか.コピーするオブジェクトのアドレスを比較すると、ブランチが遅くなります.
2つ以上のオブジェクトに機能する関数がある場合は、その関数に渡されるオブジェクトが実際に同じオブジェクトであることを確認する必要があります.

Item 12. オブジェクトのすべての部分をコピー


派生クラスのレプリケーション関数を自分で作成する場合は、基本クラスのレプリケーションが漏れないようにする必要があります.
基本クラスはprivateメンバーである可能性が高いため、直接触るのは難しい.
逆に、派生クラスのレプリケーション関数でベースクラスのレプリケーション関数を呼び出す必要があります.