Effective C++ノート--設計と声明


Effetive C++中国語版第三版
1.インタフェースを正しく使用し、誤用されにくい
ユーザーがどのようなエラーを犯すかを予測
たとえば関数
string toString(int month, int day, int year);  

審査メカニズムがない場合、ユーザーはパラメータを乱順に記入し、規則に従ってパラメータを記入しない可能性があります.ここでは、日付オブジェクトをカプセル化して、ユーザー仕様を使用することができます.
string toString(Month &m, Day &d, Year& y);
class Month{
public:
    static Jan() { return Month(1); }
    ....
private:
    explicit Month(int m);
};
string toString(Month::Jan(), ....);

2.デザインclassはデザインtypeのようです
この点には、classの作成、破棄、付与、値制限、演算子操作など、classを言語の組み込みタイプとして実装する必要があることをプログラマに警告する著者の経験が含まれています.
3.pass-by-reference-to-const置換pass-by-value
カスタムタイプで値を渡すと、メモリに実パラメータのコピーが表示され、関数で操作されるのもこのコピーです.これは、値が渡されると次のことを意味します.
  • コピー構造
  • 関数戻り時析
  • オブジェクトの切断(派生クラスが実パラメータである場合)を引き起こす可能性がある
  • .
    代価はとても大きいです!
    したがって,参照伝達の方式を導入する.値伝達時形パラメータは、変調関数スタック空間上に実パラメータの値を配置する空間を開き、実パラメータのコピーを形成する.参照伝達の場合、パラメータも局所変数としてスタック空間にメモリを開いたが、このメモリには実パラメータ変数のアドレスが格納されており、このアドレスの変数値を変更することで、関数が戻ると実パラメータが変化し、値伝達は変化しない.組み込みタイプの場合、値伝達効率は伝達参照よりも高いことがよくあります.これはSTLの反復器と関数オブジェクトにも適用されます.著者らは,ここでは主に値伝達がオブジェクト切断の問題を引き起こすことを強調した.
    引用とポインタの違いについて簡単に議論する
  • プログラムはコンパイル時にポインタと参照をそれぞれシンボルテーブルに追加し、シンボルテーブルには変数名と変数アドレスが記録されている.ポインタ変数の変数アドレスは、シンボルテーブルにポインタ変数のアドレス(指す変数のアドレスではなく)が格納され、参照される変数アドレスは参照対象のアドレス値である.したがって、ポインタは、強制型変換を指すこともできるが、参照は初期化されると変更できない.
  • ポインタの値は、あるメモリのアドレスであり、参照される値は、あるメモリの別名である.
  • sizeofポインタはマシンワード長であり、sizeofリファレンスはインデックス対象のサイズである.

  • 4.オブジェクトを返さなければならない場合は、そのreferenceに戻ることを妄想しないでください
    スタックへの参照を返す-まずい
    元の減少戻りタイプが参照である理由は、返される可能性のある参照が関数スタック上のローカル変数を指し、その関数が返されるとローカル変数が破棄され、このreferenceは未定義になります.
    const Object& func(){
        Object ob();
        ....
        return ob;
    }

    上記の場合、リファレンスは別の元のオブジェクトの別名であるため、リファレンスをインデックス化するには、このような元の変数が存在する必要があります.これは、参照のために関数に元のオブジェクトを定義する必要があることを意味します.これにより、関数でコンストラクション関数を呼び出し、プログラム効率を低下させます.
    スタックへの参照を返す-まずい
    スタック上の参照を返すと、より悪い状況になります.次の状況を考えます.
    const Object& func(){
        Object* ob = new Object();
        ...
        return *ob;
    }

    リソースを申請した後、リソースを解放することを忘れないでください.そうしないと、メモリが漏洩する可能性があります.しかし、ここでdelete obを関数内で呼び出すと、*obが空になり、参照も空になります.delete操作を行わないとメモリが漏洩するため、参照を返すときに関数にスタック上のオブジェクトを作成することを避ける必要があります.
    新しいオブジェクトの正しい書き方を返さなければなりません.
    実際には、コンストラクション関数が呼び出されます.複数の関数呼び出しの場合、効率が低下する可能性がありますが、ローカル変数を作成する方法を省くことができます.
    const Object func(){
        return Object(); #        
    }

    5.メンバー変数をprivateとして宣言
    //