STL vector の例外のキャッチについて – プログラミング – Home

STL vector の例外のキャッチ...
 
通知
すべてクリア

[解決済] STL vector の例外のキャッチについて


Takahashi
 Takahashi
(@Takahashi)
ゲスト
結合: 22年前
投稿: 45
Topic starter  

皆様、こんにちは。
高橋と申します。いつもお世話になっております。

環境は、Windows XP, VC ++ .NET 2003, コマンドコンソール(MFC + ATL)
で開発しております。

スレッドをいろいろ拝見してみると、STLなるものが
なにやら便利そうなので、試しに使用してみたのですが、
例外の件で、何を catch したらよいかがわからず
皆様の意見を拝借いたしたく、質問にまいった次第です。

以下で例外をキャッチできることは確認いたしました。

・・・(省略)

#include <vector>

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
_tprintf(_T(致命的なエラー : MFC の初期化ができませんでし
た。\n));
return 1;
}

try{
vector<int> i(-1);
}
catch(logic_error e){
cout << e.what();
char c;
cin >> c;
}

return 0;
}

logic_error でキャッチしているのは、ソースを追ったところ
いろいろな例外クラスの親になっていたからなのですが、
この方法が一般的なのでしょうか?
なにげに例外の内容などもわかって(文字列でですが・・・)

catch(...){
}

とするより良いと思ったからなのですが、
実際の所は、どうなんでしょうか?

せっかくの例外なので、起こりうる全ての例外をもれなく catch して、
例外処理をした方が、正当なような気もするのですが・・・

なにぶん、STLなる物を初めて使用したもので、
見当違いのことを言っているかもしれませんが、
どうぞ、よろしくお願いいたします。


引用未解決
トピックタグ
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> logic_error でキャッチしているのは、ソースを追ったところ
> いろいろな例外クラスの親になっていたからなのですが、
> この方法が一般的なのでしょうか?

ここで実際に発生しているのはstd::length_errorです。
そして,std::length_errorはstd::logic_errorを継承しているため,
catchできているようです。

> とするより良いと思ったからなのですが、
> 実際の所は、どうなんでしょうか?

std::length_errorをcatchしたいのであれば,
catch (const std::length_error & e)
のように,リファレンスで受けるのが普通です。
#詳しくはMore Effective C++の項目13を参照のこと。

ちなみに,std::logic_errorやその基底クラスであるstd::
exceptionでcatchしたいのであれば,
絶対にリファレンスで受けなければいけません。
そうしないと,オブジェクトのslicingが起きて,
例えばwhatメンバ関数が使い物にならなくなります。

ちなみに,
try {
/* ... */
} catch (std::exception & e) {
std::cerr << std::exception::what : << e.what() << std::endl;
} catch (std::logic_error & e) {
std::cerr << std::logic_error::what : << e.what() << std::endl;
} catch (std::length_error & e) {
std::cerr << std::length_error::what : << e.what() << std::endl;
}
のように,基底クラスから書いていくと,
最初に基底クラスで引っかかります。
例外ハンドラは派生クラス側から書く必要があります。
#ちなみに,constに特別な意味はないです。

> せっかくの例外なので、起こりうる全ての例外をもれなく catch して、
> 例外処理をした方が、正当なような気もするのですが・・・

自分で処理できる例外はcatchして処理する,
自分で処理できない例外は放っておく,というのが例外処理の基本になると思います。


返信引用
Takahashi
 Takahashi
(@Takahashi)
ゲスト
結合: 22年前
投稿: 45
Topic starter  

YuOさん、レスありがとうございます。
大変丁寧な回答ありがとうございました。

> catch (const std::length_error & e)
> のように,リファレンスで受けるのが普通です。
> #詳しくはMore Effective C++の項目13を参照のこと。
>
> ちなみに,std::logic_errorやその基底クラスであるstd::
> exceptionでcatchしたいのであれば,
> 絶対にリファレンスで受けなければいけません。
> そうしないと,オブジェクトのslicingが起きて,
> 例えばwhatメンバ関数が使い物にならなくなります。

なるほど、参照受けなんですか。
確かに、調べてみると exception に what が virtual
で定義されていているので、length_error のエラーメッセージが
消えちゃいますね。
コストの面から考えても、参照受けの方がいいようですね。
貴重なアドバイスありがとうございます。

> 自分で処理できる例外はcatchして処理する,
> 自分で処理できない例外は放っておく,というのが例外処理の基本になると思います
> 。

確かにそうですね、ずいぶん前に何かの本で読んだことがあるのですが、
忘れていました。(忘れやすい自分に反省します。)

しかし、STLは奥が深そう・・・
今日ちょっとSTLについて書かれたホームページを読んで、
使えるような気になっていたんですが、細かいところが
こうダメだと実践で使用するのは、まだ先になりそうです。
しかし、STLはちょっと触っただけでも有効性が理解できたので
(全てではありませんが・・・)
YuOさんが、ご紹介なさってくれた本などSTLについて書かれた本を探して、
自分でもう少し勉強してみます。

YuOさん、どうもありがとうございました。


返信引用
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 23年前
投稿: 310
 

例外処理と、STLについては、直接関係ないような・・・


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました