#11 C++で学ぶエラーハンドリングの基本

C++のエラーハンドリングにはtry・catchという仕組みがありますが、実行速度を重視する言語らしく、使い方には独自の考え方があります。この記事では、C++におけるエラーハンドリングの基本と、代替となる書き方を解説します。

try・catchの基本

try {
    if (b == 0) {
        throw std::runtime_error("0では割れません");
    }
} catch (const std::exception& e) {
    std::cout << e.what() << std::endl;
}

throwでエラーを投げ、catchで受け止めるという流れは、Javaなどと似ています。e.what()で、投げられた例外のメッセージを取り出せます。

複数の種類の例外を扱う

try {
    // 何らかの処理
} catch (const std::out_of_range& e) {
    std::cout << "範囲外です" << std::endl;
} catch (const std::exception& e) {
    std::cout << "その他のエラー: " << e.what() << std::endl;
}

より具体的な例外の種類を先に、汎用的なstd::exceptionを後に書くのが基本です。

戻り値でエラーを表す方法も広く使われる

C++では、try・catchの仕組み自体に実行速度の面でのコストがあるとされ、パフォーマンスが重視される場面では、Goのように「戻り値でエラーを表す」書き方も好まれます。

#include 

std::optional divide(int a, int b) {
    if (b == 0) {
        return std::nullopt;
    }
    return a / b;
}

auto result = divide(10, 0);
if (!result.has_value()) {
    std::cout << "計算できませんでした" << std::endl;
}

std::optionalは「値があるかもしれないし、無いかもしれない」ことを表す型で、例外を投げずに失敗を表現する現代的なC++の書き方の1つです。

noexceptで例外を投げないことを明示する

絶対に例外を投げない関数には、noexceptというキーワードを付けることができます。

int add(int a, int b) noexcept {
    return a + b;
}

コンパイラがこの情報をもとに最適化を行えるほか、関数の使用者に対しても「この関数は例外を心配しなくてよい」という意図を伝えられます。

C++ならではの注意点

C++には、Javaのような「チェック例外」の仕組みがなく、どんな例外が発生しうるかは実装を読むかドキュメントで確認する必要があります。また、プロジェクトによって「例外を使う方針」と「戻り値で表す方針」のどちらを採用しているかが異なるため、参加するプロジェクトの方針を最初に確認しておくことが大切です。

まとめ

C++のエラーハンドリングはtry・catch・throwが基本ですが、std::optionalのように戻り値でエラーを表す書き方も広く使われます。プロジェクトの方針を確認しながら書き方を合わせましょう。


本ページはプロモーションを含みます。

参考書籍(PR)

C++をもっと学びたい方には「新・明解C++入門編」がおすすめです。


PR

コードを書かずに自動化したい方へ

「学んだけど自分の作業に組み込む時間がない」という方向けに、ダブルクリックで動く Windows専用の自動化ツールをオーダーメイドで作成しています。気になる方は こちらをご覧ください。

コメント

このブログの人気の投稿

#25 Rustで学ぶAI API(ChatGPT等)の呼び出し方の基本

#8 C++で学ぶ文字列操作の基本

#16 TypeScriptで学ぶ辞書型(マップ)の基本