「boost::exception」の版間の差分
提供: C++入門
細 (Daemon がページ「Boost exception」を「Boost::exception」に、リダイレクトを残さずに移動しました) |
細 (Daemon がページ「Boost::exception」を「boost::exception」に移動しました) |
||
(同じ利用者による、間の1版が非表示) | |||
行3: | 行3: | ||
--> | --> | ||
− | boost::exception は、[[boost]] | + | [[boost::exception]] は、[[boost]]で提供される例外クラスです。[[boost::exception]] を[[継承]]し、独自の例外を作成します。 |
読み方 | 読み方 | ||
− | ;boost exception: ぶーすと えくせぷしょん | + | ;[[boost::exception]]: ぶーすと えくせぷしょん |
__TOC__ | __TOC__ | ||
行244: | 行244: | ||
* [[C++ライブラリ]] | * [[C++ライブラリ]] | ||
+ | * [[std::exception]] |
2013年3月23日 (土) 16:34時点における最新版
boost::exception は、boostで提供される例外クラスです。boost::exception を継承し、独自の例外を作成します。
読み方
- boost::exception
- ぶーすと えくせぷしょん
目次
概要
例外にエラーに関連する情報(ソースコードのファイル名、行番号、関数名、クラス名)いった情報を付加したり、メッセージを簡単に追加するための例外のフレームワークです。
ヘッダファイル
#include <boost/exception/all.hpp>
単純な例
ソースコード
#include <boost/exception/all.hpp> #include <iostream> #include <string> #include <exception> using namespace std; class my_ex : public boost::exception, public std::exception { public: string m_msg; ~my_ex () throw() {} virtual const char* what() const throw() { return m_msg.c_str(); }; my_ex(const string msg) : std::exception(), m_msg(msg) {} my_ex() : std::exception(), m_msg("my_ex") {} }; int main() { try { throw my_ex(); } catch (my_ex &ex) { cerr << "my exception catch" << endl; cerr << ex.what () << endl; } catch (exception &ex) { cerr << "std exception catch" << endl; cerr << ex.what () << endl; } catch (...) { cerr << "unknown" << endl; } exit (0); }
コンパイル
g++ -I/usr/local/include boost_exception.cpp
実行例
% ./a.out my exception catch my_ex
情報を付加する例
エラーメッセージを表示する場合、そのエラーがプログラム中のどこで発生したものかを含めておかなければ、エラーの原因を特定するのが困難になることもあります。 プログラム中の「どこで」というのは、
- ソースコードのファイル名
- ソースコードの行番号
- 関数名、クラス名
などです。
関連するパラメータの情報も必要になります。
- ファイルの open に失敗したなら、ファイルのパスやファイル名が必要です。
- メモリのアロケートに失敗したなら、確保しようとしたメモリサイズなどがあると良いでしょう。
例外を送出する場合には、そういった情報を exception に含めて、 throw し、例外のメッセージをエラーログに出力しておくことで、事故発生時の助けになります。
C++ でいえば、
- __FILE__
- __LINE__
- __PRETTY_FUNCTION__
といった情報を出力します。
これらの情報を毎回、例外のパラメータに設定するのは、面倒です。 また、そういった「よくあるコーディング」を毎回マイクロにするのは、骨が折れますし、生産的ではありません。
そういったときには、
- BOOST_THROW_EXCEPTION
- diagnostic_information()
を利用することで、開発効率が改善できます。
ソースコード
#include <boost/exception/all.hpp> #include <iostream> #include <string> #include <exception> #include <boost/throw_exception.hpp> using namespace std; class my_ex : public boost::exception, public std::exception { public: string m_msg; ~my_ex () throw() {} virtual const char* what() const throw() { return m_msg.c_str(); }; my_ex(const string msg) : std::exception(), m_msg(msg) {} my_ex() : std::exception(), m_msg("my_ex") {} }; int main() { try { BOOST_THROW_EXCEPTION( my_ex() ); } catch (my_ex &ex) { cerr << "my exception catch" << endl; cerr << ex.what () << endl; cerr << diagnostic_information(ex) << endl; } exit (0); i}
コンパイル
g++ -I/usr/local/include boost_exception.cpp
実行例
what() では、 my_ex しか表示されませんが、diagnostic_information() を利用することで、ファイル名や行番号、exception をthrow した関数名が表示されています。
% ./a.out my exception catch my_ex boost_exception3.cpp(42): Throw in function int main() Dynamic exception type: boost::exception_detail::clone_impl<my_ex> std::exception::what: my_ex
さらに情報を付加する例
ソースコード
#include <boost/exception/all.hpp> #include <iostream> #include <string> #include <exception> #include <boost/throw_exception.hpp> using namespace std; typedef boost::error_info<struct err_info,std::string> ex_add_info; class my_ex : public boost::exception, public std::exception { public: string m_msg; ~my_ex () throw() {} virtual const char* what() const throw() { return m_msg.c_str(); }; my_ex(const string msg) : std::exception(), m_msg(msg) {} my_ex() : std::exception(), m_msg("my_ex") {} }; void doit1() { BOOST_THROW_EXCEPTION( my_ex()); } void doit2() { try { doit1(); } catch (my_ex &ex) { ex << ex_add_info ("doit2 catch"); throw; } } int main() { try { doit2(); } catch (my_ex &ex) { cerr << diagnostic_information(ex) << endl; } exit (0); }
コンパイル
g++ -I/usr/local/include boost_exception5.cpp
実行例
doit1のcatch() 中で、追加した情報が含まれていることが確認できました。
% ./a.out boost_exception5.cpp(23): Throw in function void doit1() Dynamic exception type: boost::exception_detail::clone_impl<my_ex> std::exception::what: my_ex [err_info*] = doit2 catch