- 締切済み
C++の例外処理
お世話になります。 現在C++でプログラミングを行っていますが、例外処理で困っています。 次のようなコードを書きました。 try{ m_Session.DestroyDatabasePool(); }catch(CException e){ m_Share.WriteLogFile("キャッチ中", LOG_INFO ); } しかし、これだとcatchが行われず、catch(CException e)部分を(...)にすると例外処理が実行されます。 例外の詳細を知りたいので、どうしても(CException e)で行いたいです。 説明が不十分かもしれませんが、何かご存知でしたら、ご教授お願いします。
- みんなの回答 (7)
- 専門家の回答
みんなの回答
- ryou0607
- ベストアンサー率27% (71/261)
初心者ながらコメントさせて頂きます。 DB関連の例外処理なら、普通CDBExceptionを 使うのでは・・・ CDBExceptionで拾った例外は文字列としてm_strError に格納されています。 デバックならm_strErrorをクイックすれば何が入ってるか見れると思います。
- txrx
- ベストアンサー率45% (83/184)
えーとですね。 例外を捕らえるには、 try{ ・・・ } catch( aaa e){ ・・・ } catch( bbb c){ ・・・ } catch(...){ ・・・ } とやります。 #1の方がおっしゃっているのは、throwしている例外を聞いているのです。 つまり、使用しているメソッドが何かをスローしているのであれば、スローした型を知っている必要があります。 型が分からなければ、catch(...)で全ての例外をキャッチするしかありません。 dainnnさんは、CException をキャッチしたいのですが、このためには、m_Session.DestroyDatabasePool()が、CException をスローしていなければ、絶対にキャッチできません。 そこで#3さんが言うには、DestroyDatabasePoolは、CException またはその他を故意にスローする仕様ではないとおっしゃているのです。 その補足で、例外の種類が記述されていますね! これは、メモリのアクセス違反です。 つまりシステムがスローした例外です。 これは、CException 型ではないので、catch(...)でしかキャッチできない訳です。 結論から言うと、メモリのアクセス違反が原因なので、例外をキャッチしても問題の詳細は不明と思います。 それで、例外の質問の回答ですが、DestroyDatabasePoolメソッドが内部に throw CException e; ↑この記述が無ければ、catch(CException e)でキャッチできないと言う事になります。
- namachu
- ベストアンサー率44% (8/18)
>いや、だとすれば catch (...) に捕まるはずがない。 | m_Share.WriteLogFile(szCause, LOG_INFO )でメモ帳に結果が出力するようにしています。メモ帳への出力は問題なく動きます。(例外処理が実行できてないので出力できていませんが、他の部分では出力できています) ここの部分から、そもそもcatch (...) に捕まっていると思い込んでいると想像してます。 もし最近のバージョンは例外を発生するようになっているとすれば OException にしたら捕まえられるかもしれません。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> m_SessionはOsessionクラスの変数名です。OsessionクラスはオラクルDBを操作するためのクラスです。 それが MFCで定義された例外:CExceptionをthrowするとは考え難いのですけど。 > 手元にあるマニュアルを見る限りでは、> DestroyDatabasePool() は例外が発生するようには書かれていません。 > それが正しい動作だと思えます。 いや、だとすれば catch (...) に捕まるはずがない。
- namachu
- ベストアンサー率44% (8/18)
まず、環境を詳しく書きましょう。 単にC++の質問と言っても処理系やクラスライブラリが色々あります。 超能力者ではありませんので、あなたがどんな環境で開発しているのかは他に人にはわかりませんよね。 m_Session という書き方や CException から、Microsoft の VC++ を使用している。 DestroyDatabasePool() や COraDB から、Oracle Objects for OLE C++ Class Library を使っていると想像して回答します。 手元にあるマニュアルを見る限りでは、DestroyDatabasePool() は例外が発生するようには書かれていません。 それが正しい動作だと思えます。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> このコードの中で、m_Session.DestroyDatabasePool(); > 部分でエラーが起こったので、例外処理を行いました。 僕の質問に答えてください。ここで何が throw されるのですか? CException では'ない'のでは? m_Session は何ですか? クラスのインスタンス? MFCが提供しているものですか?
補足
m_SessionはOsessionクラスの変数名です。OsessionクラスはオラクルDBを操作するためのクラスです。 OsessionクラスのDestroyDatabasePool()メソッドの中身がわからず、何がthrowされているかわかりません。 色々調べて解らなかったので投稿したのですが、質問の内容が曖昧でした。 もう一度しっかりコードを調べてみます。すみませんでした。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
m_Session.DestroyDatabasePool() は何を throw するのですか? CException では'ない'のでは?
補足
ご回答ありがとうございます。 Cを始めたばかりで、例外処理についてわかっていないので、例外処理を行う前段階から説明します。 最初にこのようなコードを書きました。 ・ ・ ・ oresult COraDB::TerminateDatabasePool() { m_Session.DestroyDatabasePool(); return m_Session.Close(); } ・ ・ ・ このコードの中で、m_Session.DestroyDatabasePool(); 部分でエラーが起こったので、例外処理を行いました。そして、エラーの詳細が知りたくて、次のようにしました。 oresult COraDB::TerminateDatabasePool() { try{ m_Session.DestroyDatabasePool(); }catch(CException e){ TCHAR szCause[255]; e.GetErrorMessage(szCause, 255); m_Share.WriteLogFile(szCause, LOG_INFO ); } return m_Session.Close(); m_Share.WriteLogFile(szCause, LOG_INFO )でメモ帳に結果が出力するようにしています。メモ帳への出力は問題なく動きます。(例外処理が実行できてないので出力できていませんが、他の部分では出力できています) 部分的でわかりにくいかも知れませんが、よろしくお願いします。例外処理のやり方が違っていたらすいません。
補足
色々と勉強不足でした。すみません。 環境としては、言語C++、データベースはOracle9iでOracle Objects for OLE9.2.0.4.8を使用しています。 C++でファイル名.exeという実行ファイルを作成し、サービスとして起動しています。このサービスを停止するときに、 「ファイル名.exe -アプリケーションエラー- "0x01d87008"の命令が"0x000000d9"のメモリを参照しました。メモリが"written"になることはできませんでした。」 というエラーが起こりました。このエラーが起こる場所をログをメモ帳に出力することで調べました。その結果、DestroyDatabasePool() 部分で問題が発生していました。Oracle8iでは、問題なく停止できていたので、Oracleかoo4oのバージョンの問題でしょうか?