

No.4ベストアンサー
- 回答日時:
これは、「例外処理」のためのものです。
動きとしては、
try { ... } の中で発生した「例外」に対する処理を、 catch { ... } の中に記述しますということになります。
これは、例外(おおざっぱに言えば、内部的なエラー)の「発見」と「発生」と、「リカバリ」に関わる分離の思想から考えられたものです。
例外処理がない場合、エラーの処理は、
・エラーが発生してないかどうか確認する
・エラーが発生していたら、その場で処理する
ということになります。
この方法には、問題がああって、本来の処理とエラー処理が混在して処理の見通しが悪くなるということになります。
例えば、以前の(失敗したら NULL を返す仕様の new 演算子の場合)
classA a = new classA(1, 0);
if (a == 0)
goto エラー処理;
classA b = new classA(1, 1);
if (b == 0)
goto エラー処理;
など。
これに対して、最近の(失敗したら、bad_alloc 例外をスルーする ) new だと、
try
{
classA a = new classA(1, 0);
classA b = new classA(1, 1);
}
catch(bad_alloc) // これは、new で失敗した時に投げられる例外
{
エラー処理
}
となります。
こうすれば、if (a == 0) が本来の処理ではなく、エラーチェックだったのがわかります。
また、往々にして、エラーの検出箇所(それがエラーだったとわかる場所)と、エラーの発生場所(エラーを発生させてしまった場所)は違うものです。
例えば、平方根を算出する関数はマイナスの引数を受け付けません。このため、普通は関数の中で引数がマイナスでないかどうかチェックをします。
おかしな引数を渡していれば、関数の中で引数がおかしいかどうかわかります。
しかし、この間数の中では、なぜ引数がおかしいのかはわかりません。
入力ミスなのか、計算ミスなのか。
一方で、引数がおかしくなった原因は、この間数を呼び出す箇所(の近く)にあることが多いわけです。
ですから、おかしな引数のリカバリは、こちら(発生場所)で行う方が妥当です。
もちろん、関数を呼び出す前にあらかじめ引数の妥当性をチェックするというのも正しい考え方です。
ただ、場合によっては、通常処理の流れでプログラムを作り、その処理の中で(この部分を try で囲む)エラーが検出された箇所(実際には、例外処理がスルーされる場所)の情報をもとに、エラーのリカバリ(ここが、catch セクション)を行うという形にするとすっきりする場合があります。
No.3
- 回答日時:
Javaはまだましですが、C++の場合、ありとあらゆる箇所で例外が送出される可能性があります。
特にテンプレートを使った場合は、普通に演算子を使っただけでも例外に配慮する必要があります。では、try~catch(正確には「監視ブロック(try-block)」といいます)は具体的にどんなところで使うかですが、送出された例外を処理することができる箇所、または他の例外に置換すべき場所で使用します。
送出された例外を処理することができない箇所に監視ブロックを入れてみても、どうすることもできずに、(臭いものに蓋をするように)単に例外を捨ててみたり、abort等で異常終了させるしかなくなります。例外が発生したときに、リソースの解放や状態の巻き戻しを行うためだけであれば、監視ブロックではなくデストラクタを使うべきです(Javaなら仕方ないでしょうが)。
別の例外に置換すべき場合というのは、モジュールの内部で発生した例外を外部に通知する場合に、実装の詳細に依存した例外から外部とのインタフェース用の例外に治してあげる必要がある場合などです。
例外処理というと、単に監視ブロックの使い方だけだと誤解されがちですが、実際には監視ブロックを使わない箇所での例外の扱いの方がずっと難しかったりします。「例外安全」または「exception safe」というキーワードで検索すれば、ある程度情報が得られるかと思います。
No.2
- 回答日時:
同じく初心者ですが、おおまかに「予測不可能なエラー」対応に try/catch を使用します。
例えば、ファイルが存在しないとか、ユーザーが許容範囲を越える文字列を入力したとかは「予測可能」なので通常の if/else で対応して、
例えば、データベースとの接続が途中で切断されるなどは「予測不可能」なので try でつかまえて catch 節の中で対応する。その箇所で対応不能なら再度例外を throw する。
人によっては、ファイルの存在を確認せずにオープンしてみて、「ファイルが存在しない例外」を catch するようなコーディングをするかも知れませんが、私は好きでない。
この回答へのお礼
お礼日時:2007/03/19 09:50
回答ありがとうございます。
「予測可能」 =if/else
「予測不可能」=try/catch
ということですが、いかんせん初心者なもんで「予測可能」と「予測不可能」の違いがいまいちわかっていません。
データベースとの接続が途中で切断されるのは「予測不可能」となっていますが、それは、いつそんな事態が発生するかなんて「予測不可能」である、という意味でしょうか?
せっかく教えていただいたのに何だかすいません。
勉強あるのみですかね・・・。
No.1
- 回答日時:
例外エラーが発生する可能性がある場合に利用します。
基本的に、tryで正常処理を行い、catchで例外エラーをキャッチしてエラー処理を行います。
Javaだと、仮にこんなプログラム
public class test {
public static void main(String[] args) {
try {
String[] hoge = new String[] {"abc", "def", "ghi"};
for(int i = 0; i <= hoge.length; i++) {
System.out.println(hoge[i]);
}
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("例外エラーが発生した場合に処理する");
System.out.println("配列要素の不足");
e.printStackTrace();
} finally {
System.out.println("正常終了、例外エラー、どちらの場合でも必ず最後に処理する");
System.out.println("処理の終了");
}
}
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
String""から型'Double'への変...
-
お助けください!VBAのファイル...
-
UserForm1.Showでエラーになり...
-
【VBA】ワークブックを開く時に...
-
ACCESSで値を代入できないとは?
-
文字列内で括弧を使うには
-
VB.NETでMessageBoxが表示され...
-
ADO 「認証に失敗しました」
-
Findプロパティを取得できません
-
現在、QueryTableが設定されて...
-
ApplicationとWorksheetFunctio...
-
VBA データ(特定値)のある最...
-
Access クリップボードにデータ...
-
エクセル関数式=ABSで#VALUE!...
-
【Access】Excelインポート時に...
-
VBAで変数を含むSQL文を使用し...
-
【エクセル】UserFormで作った...
-
Nullの使い方が不正ですのエラ...
-
ExecuteNonQueryメソッドの戻り値
-
VB6でEndステートメントに変わ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UserForm1.Showでエラーになり...
-
お助けください!VBAのファイル...
-
【VBA】ワークブックを開く時に...
-
VBAでfunctionを利用しようとし...
-
String""から型'Double'への変...
-
実行時エラー 438 の解決策をお...
-
マクロで"#N/A"のエラー行を削...
-
文字列内で括弧を使うには
-
レコード登録時に「演算子があ...
-
【Access】Excelインポート時に...
-
インポート時のエラー「データ...
-
Filter関数を用いた結果、何も...
-
ApplicationとWorksheetFunctio...
-
On ErrorでエラーNoが0
-
Excel vbaについての質問
-
ACCESSで値を代入できないとは?
-
VBA データ(特定値)のある最...
-
【VBAエラー】Nextに対するFor...
-
「実行時エラー '3167' レコー...
-
実行時エラー'-2147467259(8000...
おすすめ情報