「boost::exception」の版間の差分

提供: C++入門
移動: 案内検索
(ページの作成:「<!-- vim: filetype=mediawiki --> boost::exception は、boostで提供される例外クラスです。boost::exception を継承し、独自の例外を作成...」)
 
行7: 行7:
 
読み方
 
読み方
  
__TOC__
+
;boost exception: ぶーすと えくせぷしょん
  
;boos::exception: ぶーすと えくせぷしょん
+
__TOC__
  
 
== 概要 ==
 
== 概要 ==

2013年3月3日 (日) 15:23時点における版


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

関連項目