例外処理
C++の文法で例外処理というのがある。まあC++の教科書なら大抵載っていると思うがこんなの
try{ throw "error"; } catch( char* e ){ cout << e; }
まあ知らない人は適当なC++の文法書でもあさってください。
例外処理をデバッグとしてでなくコードとして使う場合は大抵は基底の例外クラスみたいなのを作ってそいつを継承してそれを投げ、そして基底クラスでキャッチするという手法がある。
class Exception{ virtual char* what() = 0; }; class BufferOverFlow:public Exception{ virtual char* what(){ return "buffer overflow"; } }; try{ throw BufferOverFlow; } catch( Exception& e ){ cout << e.what() << endl; }
オブジェクト指向的な例外処理ですね(何)
でまあ、自前で基底の例外クラスを作らなくても実際にはC++は標準でstd::Exceptionというクラスは存在します。また標準的な例外もこの構造をとっています。例えば、メモリ不足でnewできなかった場合はstd::bad_allocが投げられます。こいつもstd::Exceptionを継承しています。
んでまあ仕事でこのあたりの調整をやっているんですがエラー処理関係をすべて例外を利用しようと思っていてすべてstd::Exceptionを継承させるという方法を取ろうと考えていたんですがこれが大失敗でした。や、私の考え方でなく悪いのはMicrosoftの方だが・・・。
とりあえず開発中のモジュールが例外を投げているみたいなのでstd::Exceptionでキャッチして何が起こっているか調べてみようと思った・・・すり抜けやがったorz なんでやねん、モジュール内の例外はすべてstd::Exceptionから派生させているはずなのに・・・。んで、ちょっと調べたらどうやらnew演算子が失敗しているっぽい。だったらbad_allocを投げるはずだろ?と思っていてnew演算子の中までデバッガで追ってみたら・・・なんだかいつもと景色がちがう。new演算子のソースってこんなんだっけ? と思ってたら例外を投げている場所にたどり着いてビックリ。なんだかよくわからないクラスを投げている。そのクラスの継承元をたどってみたら・・・CExceptionとかいうのにたどり着いた。
犯人はお前かMFC!!
どうやらMFCは自前でnew演算子を用意していてMFC独自の例外クラスを所有して独自の例外を投げているらしい。C++標準演算子を独自定義するなよ・・・。これじゃコードの保守とか出来ないやんけ。
というわけで、うちのグループのモジュールはMFCでは保障対象外です(ぉ