1. 導入:なぜ例外処理が必要なのか
プログラムを作成していると、「ファイルが開けない」「計算結果が異常値になった」といった想定外の事態が発生することがあります。このようなエラーが発生した際、従来のC言語的な手法では戻り値でエラーを判定するのが一般的でしたが、コードが複雑になりがちでした。そこで活躍するのがthrow文です。throw文を使えば、エラーが発生した瞬間に処理を中断し、適切にエラーを処理できる場所(catchブロック)まで一気に制御を飛ばすことができます。これにより、正常な処理とエラー処理のコードをすっきりと分離できるようになります。
2. 基礎知識:例外処理の仕組み
C++の例外処理は、「try-catch-throw」という3つの要素で構成されます。
throw:例外を「投げる」ためのキーワード。エラーが発生したことを周囲に伝えます。
try:例外が発生する可能性のあるコードを囲むブロックです。
catch:throwで投げられた例外を「受け取る」ブロックです。エラーに対する対処(ログ出力や再試行など)を書きます。
イメージとしては、バレーボールのパスのようなものです。エラーをthrowする側がボールを投げ、catchする側がそれを受け取ってゲームを立て直す、と考えると分かりやすいでしょう。
3. 実装と解決策
例外を発生させるには、標準ライブラリの
実装のステップは以下の通りです。
1. エラーが発生しそうな処理を try ブロックで囲む。
2. 特定の条件で throw 文を実行する。
3. catch ブロックで例外オブジェクトを受け取り、エラーメッセージを表示する。
4. サンプルプログラム
以下のコードをコピーして、コンパイル・実行してみてください。
include
include
void checkValue(int value) {
// 値が0以下の場合はエラーとみなして例外を投げる
if (value <= 0) {
throw std::runtime_error("エラー:値は1以上である必要があります!");
}
std::cout << "値は正常です: " << value << std::endl;
}
int main() {
try {
// 正常なケース
checkValue(10);
// 異常なケース(ここで例外が投げられ、catchへ飛びます)
checkValue(-5);
std::cout << "この行は実行されません" << std::endl;
}
catch (const std::runtime_error& e) {
// throwで投げられた例外をキャッチしてメッセージを表示
std::cerr << "例外をキャッチしました: " << e.what() << std::endl;
}
return 0;
}
5. 応用・注意点
現場で使う際の重要なポイントを2点お伝えします。
一点目は、「投げすぎないこと」です。例外はあくまで「想定外の事態」に対して使うものです。if文で制御できるような日常的な条件分岐にthrowを乱用すると、プログラムの処理速度が低下し、コードの可読性も悪くなります。
二点目は、「例外安全」です。例外が投げられると処理が途中で中断されるため、メモリの解放やファイルのクローズ処理がスキップされてしまう可能性があります。これを防ぐために、C++ではデストラクタを活用する「RAII(Resource Acquisition Is Initialization)」という設計手法を使うのが鉄則です。スマートポインタ(std::unique_ptrなど)を活用して、例外が起きてもリソースが確実に解放されるように心がけましょう。

コメント