##『More Effective C+』-異常
5043 ワード
More Effective C++
九、
RAIIとは「リソース取得は初期化時」であるため,リソースを解放しなければならない.リソースを1つのオブジェクトに格納し、オブジェクトの構造関数に依存してリソースを解放します.
リソースをオブジェクトにカプセル化することで、異常が発生した場合、オブジェクトのプロファイル時にプロファイル関数を呼び出し、リソースを解放し、リソースの漏洩を回避できます.
異常がリソース取得中に投げ出された場合は、10番目の項目を表示します.異常が解析中に発生した場合は、第11条を参照してください.
十、
「pointer class members」の代わりにスマートポインタを使用すると、リソースをローカルオブジェクトで管理し、異常が発生した場合、
十一異常(
呼び出しオブジェクトは通常の状態で破棄する .オブジェクトは 破棄される.
異常時の状況を議論し,外部の
十二、「 一致する 非常量から定数への転換 派生クラスからベースクラスへの転換 配列は、配列タイプを指すポインタ に変換される.
b.マッチング順序関数マッチングは異常放出異常放出: 十三、
関数伝達パラメータと同様に,効率と正確性のためには参照伝達を行ったほうがよい.
Catch exceptions by reference !
十四、賢明な運用
しかし、
解決策は、呼び出された関数が
また、関数ポインタで関数を呼び出すと、登録されたコールバック関数を実装する場合など、この検証も行われます.
2つ目の問題は、
3つ目の問題は、「システム」が投げ出す可能性のある
しかし、いくつかの関数が
しかし、
もう1つの方法は、
十五、異常処理(exception handling)のコストを理解する
#@author: gr
#@date: 2015-05-24
#@email: [email protected]
九、
destructors
を利用して資源の漏洩を避けるRAIIとは「リソース取得は初期化時」であるため,リソースを解放しなければならない.リソースを1つのオブジェクトに格納し、オブジェクトの構造関数に依存してリソースを解放します.
リソースをオブジェクトにカプセル化することで、異常が発生した場合、オブジェクトのプロファイル時にプロファイル関数を呼び出し、リソースを解放し、リソースの漏洩を回避できます.
異常がリソース取得中に投げ出された場合は、10番目の項目を表示します.異常が解析中に発生した場合は、第11条を参照してください.
十、
constructors
内で資源の漏洩を阻止するconstructor
で関数に異常が発生した場合、オブジェクトの構造が完了していないため、その構造関数は呼び出されません.だから私たちは構造関数を期待して整理しています.BookEntry::BookEntry(const string& name, address, const string& imageFileName, const string& audioClipFileName)
:theName(name), theAddress(address), theImage(0), theAudioClip(0)
{
theImage = new Image(imageFileName);
theAudioClip = new AudioClip(audioClipFileName); // AudioClip , Image
}
「pointer class members」の代わりにスマートポインタを使用すると、リソースをローカルオブジェクトで管理し、異常が発生した場合、
BookEntry
が自動的に破棄された場合も、指定したオブジェクトを手動で削除しないでください.十一異常(
exception
)流出禁止destructors
外呼び出し
destructor
には、次の2つのケースがあります.exception
処理機構によって異常時の状況を議論し,外部の
catch
ブロックで構造関数を呼び出し,構造関数が間違っている場合にstd::terminate()
を呼び出してプログラムを終了させる.このような状況を避けるには、catch
ブロックにtry-catch
を追加することができますが、これは極端に見えます.方法は,異常を生じる可能性のある構造関数において異常のキャプチャを行い,何もしないことである.Session::~Session()
{
try{
logDestruction(this);
}catch(...){}
}
十二、「
exception
を投げ出す」と「パラメータを渡す」または「虚関数を呼び出す」の違いを理解するcatch
句のパラメータタイプpass by reference
メソッドを使用すると、異常な修正に役立ち、効率を向上させることができ、一般的にcatch
のパラメータタイプを参照タイプとして定義します.catch
句a.タイプ変換は関数パラメータマッチングよりも少ないが、算術タイプ変換とクラスタイプ変換はサポートされず、以下のようにのみサポートされる.b.マッチング順序関数マッチングは
best-fit
で行われ、マッチングパラメータの選択が最良であり、異常問題はfirst fit
で行われ、順序に従って行われるので、サブクラス(および特殊タイプ)を汎用タイプの前に置く. Exception ex;
throw ex;
異常放出時、catchがどのようにby reference
とby value
を捕獲しても複製する必要があり、catch
句にあるのはこの異常のコピーである.異常再放出:catch (exception& ex)
{
//....
throw; // exception,
}
catch (exception& ex)
{
//....
throw ex; // exception
}
by reference
方式でexceptions
を捕捉する関数伝達パラメータと同様に,効率と正確性のためには参照伝達を行ったほうがよい.
Catch exceptions by reference !
十四、賢明な運用
exception specifications
exception specifications
とは、関数の後ろに投げ出す異常タイプを加えることです.次のようになります.void f2() throw(int); // int
void f3() throw(); //
しかし、
exception specifications
は、exception specification
に列挙されていないexception
を投げ出すと、このエラーが実行時に検出され、特殊関数unexpeted
が自動的に呼び出され、プログラムが終了するという問題をもたらす.void f1(); //f1 exception specification
void f2() throw(int)
{
//....
f1(); // f1(),
//....
}
解決策は、呼び出された関数が
exception specifications
でなければ、呼び出された関数もexception specifications
を加えないことである.また、関数ポインタで関数を呼び出すと、登録されたコールバック関数を実装する場合など、この検証も行われます.
2つ目の問題は、
exception specifications
を「タイプ引数が必要」template
に置かないことです.template
は必ず何らかの方法でそのタイプのパラメータを使用するので、template
とexception specifications
を混合して使用するべきではありません.3つ目の問題は、「システム」が投げ出す可能性のある
exceptions
を処理することである.new operator
を使用すると、bad_alloc
異常が放出される可能性があります.しかし、いくつかの関数が
exception specifications
と書かれている場合は、他のライブラリにexception specifications
がない関数を呼び出すには、これらの関数から投げ出された他の異常をUnexceptedException
異常に変換するしかありません.class UnexceptedException{};
void convertUnexcepted()
{
throw UnexceptedException();
}
set_unexpected(convertUnexpected);
しかし、
exception specification
にUnexceptedException
を加える必要があります.そうしないと、terminate
は呼び出されます.もう1つの方法は、
exceptions
を標準タイプbad_exception
に変換することであり、その実装は、予期しない関数の代替者が現在の(current)exception
を再び投げ出すと、標準タイプbad_exception
に置き換えられることに依存する.exception specifications
にbad_exception
を加えるといいです.void convertUnexcepted(){
throw; // exception
}
set_unexpected(convertUnexpected);
exception specifications
は両面刃で、「関数がどのようなexceptionを投げたいのか」という面で優れた説明をしているが、同時に「exception specifications違反」の時も結末は悲惨だ.十五、異常処理(exception handling)のコストを理解する
exception
をサポートするためには、プログラムは大量の簿記作業をしなければならない.「天下に無料の昼食はない」という理屈だ.各try
文ブロックの進入点と離脱点に記号を付けなければならない.try
文ごとに、対応するcatch
句が処理できるexceptions
型を記録しなければならない.try
文ブロックコードを用いて約5%~10%膨張し,実行速度も低下する.パフォーマンス上の問題がある場合は、分析ツール(profiler)を使用してプログラムのパフォーマンスのボトルネックを分析します.