effective c++

4335 ワード

01、C++を言語連邦とする
C++は4つのサブ言語に分けられる:C、Object-oriented C+、Template C++、STL、この4つの中で、Cが最も基本的で、Object-oriented C++が最も重要(パッケージ、継承、マルチステート、ダイナミックバインド)、Template C++(汎用プログラミング)が最も少なく、STLが最も実用的(コンテナ、反復器、アルゴリズム)である
02、できるだけconst,union,inlineで#defineを置き換える
1)マクロはコンパイラに見られず,シンボルテーブルも入れられず,位置決め,デバッグに不便をもたらす.
2)マクロはカプセル化されていない.
03、できるだけconstを使う
1)反復器はポインタに基づいて成形され,T*に似ているため,constで反復器,すなわちconst(T*)を修飾し,ポインタ自体を修飾し,ポインタは変更できず,ポインタが指す内容は変更できる.
2)関数の戻り値にconstを付けると,関数の戻り値が与えられるのを避けることができ,愚かに見えるが,できるだけミスを避けるために事前に措置をとることが望ましい.
3)定数の異なる2つのメンバ関数のみをリロードすることができ,これはC++の重要な特性である.
4)constメンバー関数がnon-constメンバー関数を呼び出すのは誤りであり、non-constメンバー関数がconstメンバー関数を呼び出すのは安全である.
04、オブジェクトが使用される前に初期化されたことを確定する
1)変数の初期化が表示する場合、その内容はランダム値であり、安全性がない.
2)メンバー変数を初期化する最良の方法は、初期化リストを使用することであり、構造関数内の初期化ではなく、最も効率的である.
05、C++コンパイラが黙々と作成して呼び出す関数を理解する
1)コンパイラはclassのdefaultコンストラクタ、copyコンストラクタ、copy assignmentオペレータ、およびコンストラクタを暗黙的に作成できます.
06、コンパイラで自動的に生成される関数を使用したくない場合は、明確に拒否する
1)コンパイラが特定の関数を自動的に生成しない場合は、privateとして宣言し、実装しません.
07、マルチステートベースクラスに対してvirtual構造関数を宣言する
1)多態性を持つベースクラスは、virtual構造関数を宣言する必要があります.classがvirtual関数を持っている場合は、virtual構造関数がある必要があります.
2)すべてのベースクラス設計の目的がマルチステートであるわけではない.例えば、標準stringとSTLはマルチステートとして使用されない.これらの関数にはvirtual構造関数があるべきではない.
08、異常を構造関数から逃がさない
1)解析関数は絶対に外に異常を投げ出さないでください.解析関数に異常が発生する可能性がある場合は、それをキャプチャしてプログラムを飲み込んだり終了したりしなければなりません.
2)他のより良い方法は、エラーが発生する可能性のある部分をメンバー関数によってユーザーに提供することであり、ユーザーはこれらの例外を処理することができ、ユーザーが呼び出しを放棄することを選択した場合、構造関数で処理することができる.
09、virtual関数は、構築または構築中に呼び出されない
1)virtual関数を呼び出す利点は、現在のクラスに対応するvirtual関数を動的にバインドできることであるが、base classが構造またはプロファイルでvirtualを呼び出す場合、derived classが構造を実行する前に、まずbase classの構造を実行する.この場合、derived classはまだ初期化されていないため、C++コンパイラはderived classのvirtual関数を無視する.derived classのvirtual関数に動的にバインドされません.だから運行結果は予想通りではない.
10、operator=reference thisを返す*
リロード演算子関数は値を返さなくてもよいが、a=b=c=3のような連鎖運転形式があることを考慮すると、obj&operator=(const obj&rhs){...return*this}などの自己への参照を返すことが望ましい.
11、operator=で「自己複製」を処理する
obj &operator=(const obj &rhs)
{
	delete this.ts;
	this.ts = new things(*rhs.ts);
	return *this;
}

上記は等号演算子リロード関数の本体部分ですが、rhsがthisと同じオブジェクトを指していると仮定するとエラーが発生します.
最初の行ts,thisはrhsと同じであるため,2行目のrhs.tsは実はdeleteされているので、newが出てきた相手に問題があります.
したがって、「自己複製」時にこのような悲劇が発生することを避けるためには、関数の先頭でthisとrhsが同じかどうかを判断し、同じ場合はthisを直接返す必要があります.if(this==rhs)return this;.
12、対象を複製する時、各成分を忘れないでください
1)コピーコンストラクタと代入オペレータを作成するときは、特に追加したメンバー変数の後、コピー関数に追加するメンバー変数を忘れないでください.
2)コピーコンストラクタとコピーオペレータに重複するコードを書きたくない場合は、呼び出しのために個別の関数に配置できます.通常はinitと名付けられます.
13、対象で資源を管理する
1)申請空間から戻ったポインタでインテリジェントクラスポインタをインスタンス化する,いわゆるリソースを管理対象に入れる,では、クラスが破棄される(一般的には役割ドメインを終了する)と、クラスの構造関数はポインタが指す空間リソースを自動的に解放し、同じ原理でクラス管理スレッドでリソースをロックすることもでき、クラスが破棄される(関数を終了し、臨界領域を終了するに違いない)と、構造関数は自動的にロックを解放し、ロックを解除することを忘れてデッドロックを防止することができる.
2)2つの一般的なスマートロックはauto_ptrとshared_ptr,両者の違いは複数のauto_を持つことができないことである.ptrは同じリソースを指し、コピー構造または付与演算子でauto_を構築します.ptrクラスの場合、前のauto_ptrはNULLを指し、shared_ptrのコピー構造は、shared_がない場合にのみ正常です.ptrがリソースを指す場合に解放されます.
14、資源管理クラスでcopy行為に注意する
1)スマートポインタのようなものを自分で実現する必要がある場合、例えばロックオブジェクトを管理する必要がある場合、この場合、copy動作(copy構造またはcopy付与)を考慮する必要があります.copy動作を望んでいない場合は、privateのcopy関数を記述して無効化する必要があります.copyが指す空間、すなわち深さコピー、または下部リソースの所有権を転送することもできます.auto_ptrと同じです.
15、資源管理クラスで原始資源へのアクセスを提供する
リソース管理クラスを使用する場合、元のリソースにアクセスする必要がある場合があります.そのため、管理クラスに元のリソースにアクセスするインタフェースを提供する必要があります.auto_ptrとshared_ptrなどのデフォルトにはget()メンバー関数があり、元のリソースポインタを返します.自分で作成したリソース管理クラスであれば、get()のような機能も提供する必要があります.
16、ペアでnewとdeleteを使用する場合は同じ形式を採用する
new式に[]が表示された場合、delete式も必ず[]を使用します.
17、独立した文で申請資源から返されたポインタをスマートポインタに置く
18、インタフェースが正しく使われやすく、誤用されにくい
1)インタフェースの一貫性と組み込み型との互換性を保つ
2)trl::shared_prtはカスタム削除器をサポートし、反発ロックを自動的に解除するなどに使用できます.
19、設計class設計type
classを設計する際には全面的、細かく考慮しなければならない.
20、pass-by-valueの代わりにpass-by-reference-to-constを用いる
内蔵タイプ、STLの反復器と関数オブジェクトはpass-by-valueを適用します.それ以外のタイプはpass-by-reference-to-constを使用することをお勧めします.これにより、より効率的で、切断の問題を回避できます.
21、新しいオブジェクトを返さなければならない場合、referenceに戻ることを妄想しないでください
pointまたはreferenceが関数の内部オブジェクトを指すことを決して返さないでください.
22.メンバー変数をprivateとして宣言する.
1、関数によるアクセスはより統一性、パッケージ性がある.
2、publicはカプセル化しないことを意味し、カプセル化しないことは変更できないことを意味し、柔軟性と拡張性が低下する.
23、むしろnon-member、non-friend関数でmember関数の代わりにする
これにより、パッケージ性、ラップ性、拡張性を向上させることができます.