7、例外処理

  • 例外処理メカニズム(例外処理機能):設計者として、プログラム全体に問題がどれほど有害であるかはわかりません。この関数のユーザーだけが問題の重大度を知っています。したがって、私たちの責任はユーザー通知し、何が起こったかをユーザーに伝えることです。例外処理メカニズムは、通知タスクを完了するために使用されます。
  • 例外処理メカニズムには、例外の識別と問題+例外処理方法が含まれます。
  • 例外が発生した後、通常のプログラムの実行が一時停止され、例外処理メカニズムが、例外を処理できるプログラム内の場所の検索を開始します。例外が処理された後、プログラムの実行は続行(再開)され、例外処理の時点から実行が継続されます。
  • スロー(スロー)例外: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;
}

再スローするときは、キーワードを書き留めるだけです。キーワードthrowcatch句にのみ表示され、キャッチされた例外オブジェクトを再度スローすると、同じタイプの別の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

おすすめ

転載: blog.csdn.net/pppppppyl/article/details/114383013