[C++] メンバコンストラクタの例外
普段からこれっぽっちも疑問に思わなかったんですが,クラスメンバのコンストラクタの例外をキャッチする方法がある(cppll:3219)とのこと.
構文はこんな感じ.
class Foo
{
Bar bar; // Bar クラスは Foo のメンバ (定義は省略)
Hoge() try : bar() {
// メンバのコンストラクトが成功したときは,
// ここに書いた Hoge のコンストラクト処理が行われる
...
}
catch (...) {
// メンバのコンストラクタが例外を投げたときはここに来る
...
} // ←ここで自動的に catch した例外が再度投げられる (VC7 は投げてくれないらしい)
};
こんなところに try-catch が書けたんだ... 全然知らなかった...
メンバコンストラクタが投げた例外は catch 節を抜けた後で自動的に re-throw されるようになっているため,そのクラス自身のコンストラクトも失敗します (cppll:3221 によれば,VC7 では標準の動作をさせるために明示的に再スローしないとダメらしいです.手元に VC7 がないので確認できないのですが).
g++-4 や VC8 (Express Edition) ではどうなるかを試してみることに.
#include <iostream>
#include <stdexcept>
using namespace std;
class B
{
public:
B() {
throw runtime_error("hoge");
}
~B() {
cout << "~B()" << endl;
}
};
class A
{
public:
// constructor
A() try : b() {
cout << "A()" << endl;
}
catch (const exception& e) {
cout << "foo" << endl;
}
~A() {
cout << "~A()" << endl;
}
private:
B b;
};
int main()
{
try
{
A a;
}
catch (const exception& e)
{
cout << "bar" << endl;
}
return 0;
}
g++-4.1.2 (Gentoo 4.1.2) と,VC8 Express Edition (14.00.50727.42) で試したところ,どちらもいずれの実行結果が得られました.
(g++-4.1.2 での結果) $ g++ test.cc $ ./a.out foo bar $
(VC8 Express での結果) $ cl /nologo /EHsc test.cc test.cc $ ./test foo bar $
ちゃんと A のコンストラクトは失敗しており,いずれも標準の動作になっています.
トラックバック
トラックバック URI: https://www.pakunet.jp/hoge/trackback/2007110401
トラックバックはありません.