- 例外処理メカニズム(例外処理機能):設計者として、プログラム全体に問題がどれほど有害であるかはわかりません。この関数のユーザーだけが問題の重大度を知っています。したがって、私たちの責任は、ユーザーに通知し、何が起こったかをユーザーに伝えることです。例外処理メカニズムは、通知タスクを完了するために使用されます。
- 例外処理メカニズムには、例外の識別と問題+例外処理方法が含まれます。
- 例外が発生した後、通常のプログラムの実行が一時停止され、例外処理メカニズムが、例外を処理できるプログラム内の場所の検索を開始します。例外が処理された後、プログラムの実行は続行(再開)され、例外処理の時点から実行が継続されます。
- スロー(スロー)例外:
throw
式は関数呼び出しのように見えます。例外はある種のオブジェクトであり、ほとんどの場合、特定の例外クラスに属します(継承システムを形成する場合があります)。
inline void Triangular_iterator::
check_integrity()
{
if(_index >= Triangular::_max_elems)
throw iterator_overflow(_index, Triangular::_max_elems);
if(_index > Triangular::_elems.size())
Triangular::gen_elements(_index + 1);
}
//iterator_overflow类的定义
class iterator_overflow{
public:
iterator_overflow(int index, int max)
: _index(index), _max(max) {
}
int index() {
return _index;}
int max() {
return _max;}
void what_happened(ostream &os = cerr) {
os << "Internal error: current index "
<< _index << " exceeds maximum bound: "
<< _max;
}
private:
int _index;
int _max;
};
- 上記の
throw
式は、2つのパラメーターを使用してコンストラクターを直接呼び出します。スローされたオブジェクトの名前を指定することもできます。
if(_index > Triangular::_max_elems)
{
iterator_overflow ex(_index, Triangular::_max_elems);
throw ex;
}
- キャッチ例外:単一の句または一連の
catch
句を使用してキャッチします。catch
この句は、キーワードcatch
+括弧内のタイプまたはオブジェクト+中括弧内のステートメントのグループ(例外の処理に使用)の3つの部分で構成されています。
catch(iterator_overflow &iof)
{
iof.what_happened(log_file);
}
- 例外オブジェクトのタイプは、各句と1つずつ比較され
catch
ます。タイプが一致する場合、句の内容が実行されます。すべてのcatch句を渡した後、通常のプログラムが再び引き継ぎます。
上に示したように、
iof
この例外オブジェクトを介して、例外クラスのメンバー関数を呼び出しますwhat_happened()
。
- 例外の完全な処理を完了できない場合は、他のcatch句の支援を求めるために、例外を再スローする必要がある場合があります。
catch(iterator_overflow &iof)
{
log_message( iof.what_happened() );
//重新抛出异常,令另一个catch子句接手处理
throw;
}
再スローするときは、キーワードを書き留めるだけです。キーワード
throw
はcatch
句にのみ表示され、キャッチされた例外オブジェクトを再度スローすると、同じタイプの別のcatch句が処理を引き継ぎます。
- あらゆるタイプの例外をキャッチしたい場合は、キャッチオールメソッドを使用できます。
//在异常声明部分指定省略号
catch(...)
{
log_message( "exception of unknown type" );
//清理(clean up)然后退出...
}
- 絞り込みの例外:
catch
句はtry
、ブロックに対応して生成する必要があります。try
ブロックはキーワードtry
で始まり、その後に中括弧で囲まれた一連のプログラムステートメントが続きます。catch
この句はtry
ブロックの最後に配置されます。つまり、ブロックでtry
例外が発生した場合、次のcatch
句で処理されます。 - 関数が例外をスローした後、例外処理メカニズムは、例外がスローされた場所のチェックを開始し、それが
try
ブロック内にあるかどうかを判断しますか?そうである場合は、対応する句をチェックcatch
して、この例外を処理できるかどうかを確認します。機能している場合は、例外が処理され、プログラムは実行を継続します(実行されたcatch
句の後のステートメントの最初の行から開始)) 。 try
ブロック内にない場合、例外処理メカニズムは結局関数を実行する権利を持ち、残りのコンテンツは実行されません。ただし、例外処理メカニズムは、関数の呼び出し側の型に一致するcatch
句を引き続き検索します。- 場合は、関数呼び出しチェーンがされて継続的に解明されるまで、
main()
もし適切なcatch
句が見つからない、それが標準ライブラリを呼び出すので、すべての例外は、処理されるべきであるとC ++規定は、提供terminate()
-itsデフォルトの動作が中断しているの実行全体のプログラムを。 - ステートメントが例外を引き起こす可能性があり、それが
try
ブロック内にない場合は、この関数で例外をキャッチしてはなりません。 - すべての関数がすべての可能な例外を処理する必要があるわけではありません。
- 関数
try
ブロックで例外が発生したが、それに対応するcatch
句がない場合、関数は中断され、例外処理メカニズムが引き継ぎ、関数呼び出しチェーンに沿ってトレースバックし、次のcatch
句を検索します。条件を満たす。 - スローされたC ++例外に直面しても、プログラムのどこかに対応する
throw
式があります。 - C ++例外を、セグメンテーション違反やバスエラーなどのハードウェア例外と混同しないでください。
- 以下の関数エラーは、関数実行の開始時に割り当てられたリソースが最終的に解放されるという保証はありません。process()が例外をスローした場合、リソースを解放するための後続の2つのステートメントは実行されません。
extern Mutex m;
void f()
{
//请求资源
int *p = new int;
m.acquire();
process(p);
//释放资源
m.release();
delete p;
}
- tryブロックと対応するcatch句を追加できます。catch句は、すべての例外をキャッチし、リソースを解放して、例外を再スローします。(ただし、リソースの解放に使用されるプログラムコードは2回出現する必要があります(catchとcatchの後に存在する必要があります))
- リソース管理(リソース管理):リソース要求は、初期化フェーズ中に行われます。
- オブジェクトの場合、初期化操作はコンストラクターで行われ、リソース要求もコンストラクターで完了する必要があります。リソースの解放は、デストラクタで完了する必要があります。
#include <memory>
void f()
{
auto_ptr<int> p(new int);
MutexLock ml(m);
process(p);
//p和ml的destructor会在此处被调用
}
- 例外処理メカニズムが関数を終了する前に、C ++は、関数内のすべてのローカルオブジェクトのデストラクタが呼び出されることを保証します。
auto_ptr
これは、標準ライブラリが提供するクラステンプレートであり、new
式によって割り当てられたオブジェクトを自動的に削除します。使用する前に#include <memory>
、derefrence(*
)演算子とarrow(->
)演算子をオーバーロードするヘッダーファイルをインクルードして、次のように使用できるようにします。通常のポインタauto_ptr
オブジェクト。
auto_ptr<string> aps(new string("hello"));
string *ps = new string("hello");
if((aps -> size() == ps -> size()) && (*aps == *ps))
//true
new
式がプログラムの空き領域から十分なメモリを割り当てることができない場合、bad_alloc
例外オブジェクトがスローされます。bad_alloc
例外がスローされないようにしたい場合は、を実行できますptext = new (nothrow) vector<string>;
。そのため、new
操作が失敗した場合は、が返され0
ます。誰ptext
もがそれを使用する前にそれがそうであるかどうかを確認する必要があり0
ます。catch(bad_alloc)
オブジェクトを宣言せず、キャッチされた例外のタイプのみに関心があり、catch句でオブジェクトを実際に操作することを意図していませんでした。- 標準ライブラリは、一連の例外クラスシステムを定義し、そのルートは抽象基本クラス
exception
です。exception
宣言には、スローされる例外のテキスト説明を示すためにwhat()
戻る仮想関数がありますconst char *
。#include <exception>
- 独自の記述
iterator_overflow
を標準exception
クラスシステムに統合することができ、独自の記述を提供する必要があります。what()
これにより、抽象基本クラスの例外をキャプチャすることを目的とした任意のプログラムでキャプチャできます。
//捕获exception的所有派生类
catch( const exception &ex)
{
cerr << ex.what() << endl;
}
- 以下は
iterator_overflow
それをwhat()
達成する方法です。
//运用ostringstream对象对输出信息进行格式化
#include <sstream>
#include <string>
const char* iterator_overflow::
what() const
{
ostringstream ex_msg;
static string msg;
//将输出信息写到内存中的 ostringstream对象之中
//将整数值转为字符串表示
ex_msg << "Internal error: current index "
<< _index << "exceeds maximum bound: "
<< _max;
//萃取出string对象
msg = ex_msg.str();
//萃取出const char*表达式
return msg.c_str();
}
ostringstream
このクラスは、メモリ内の出力操作とstring
オブジェクトへの出力を提供します。自動的_index
にできます、_max
そのようなオブジェクトは、ストレージ、変換アルゴリズム、その他の問題に関係なく、対応する数値文字列に変換されます#include <sstream>
。ostringstream
提供されているメンバー関数はstr()
、オブジェクトに対応する文字列オブジェクトを返すことができます。- 文字列クラスによって提供される変換関数
c_str()
は、Cスタイルの文字列を返します。 - iostreamライブラリは、対応する
istringstream
クラスも提供します。非文字列データの文字列表現を実際の型に変換します。 ifstream
コンストラクターによって受け入れられるパラメーターはではありconst char*
ませんstring
。