C++
 Computer >> コンピューター >  >> プログラミング >> C++

【C++】catchブロックと型変換の挙動を徹底解説


はじめに

この記事では、C++の例外処理におけるcatchブロックの使い方と、catchブロックにおける型変換の挙動について解説します。
まずはサンプルコードを見ながら、どのような出力が得られ、それがなぜ起こるのかを確認していきましょう。

例1:文字型をthrowした場合の挙動

#include <iostream>
using namespace std;
int main() {
    try{
        throw 'a';
    }
    catch(int a) {
        cout << "Integer value is caught :" << a;
    }
    catch(...) {
        cout << "Entering into default catch block";
    }
}

出力結果

Entering into default catch block

なぜデフォルトのcatchブロックが実行されるのか?

コードでは文字リテラル 'a' をthrowしていますが、最初のcatchブロックは int 型を受け取るように宣言されています。
'a' のASCIIコードは97という整数値だから、最初のcatchブロックに入るはずだ」と考えたくなりますが、catchブロックのマッチングではchar型からint型への暗黙の型変換は行われません

そのため、例外オブジェクトの型(char)とハンドラーの型(int)は一致せず、最初のcatchブロックはスキップされます。結果として、あらゆる型を受け取れる「...」によるデフォルトのcatchブロックが実行されるというわけです。

例2:変換コンストラクタを持つクラスの場合

続いて、別の例を見てみましょう。この例では、throwされたオブジェクトに対しては変換コンストラクタが呼び出されないことを確認します。

#include <iostream>
using namespace std;
class TestExcept1 {};
class TestExcept2 {
    public:
        TestExcept2(const TestExcept1 &e) { // 変換コンストラクタの定義
            cout << "From the Conversion constructor";
        }
};
int main() {
    try{
        TestExcept1 exp1;
        throw exp1;
    } catch(TestExcept2 e2) {
        cout << "Caught TestExcept2 " << endl;
    } catch(...) {
        cout << "Entering into default catch block " << endl;
    }
}

出力結果

Entering into default catch block

結果の解説

TestExcept1 型のオブジェクトをthrowしていますが、TestExcept2 側には TestExcept1 を受け取る変換コンストラクタが定義されています。通常の関数呼び出しであれば、この変換コンストラクタによって暗黙の型変換が行われる可能性があります。
しかし、例外処理の型マッチングではユーザー定義の変換コンストラクタは考慮されないため、「From the Conversion constructor」というメッセージは表示されず、そのままデフォルトのcatchブロックへと処理が移ります。

まとめ:catchブロックで許可される変換とは

C++の例外処理において、ハンドラーとの型マッチングで行われる変換は非常に限られています。

  • 行われない変換: 算術型間の暗黙変換(char → int など)、ユーザー定義の変換コンストラクタや変換演算子による変換
  • 行われる変換: クラス型における「派生クラス → 基底クラス」への変換のみ。派生クラス型のオブジェクトをthrowした場合でも、基底クラス型のcatchブロックで捕捉することができます。

例外処理を設計する際は、throwする例外の型とcatchブロックの引数の型を正確に一致させるか、継承階層を活用した設計にすることが重要です。意図しない場所で例外が捕捉されないよう、十分に注意しましょう。

  1. フリップフロップの種類と相互変換の方法を徹底解説

    フリップフロップ(flip-flop)は、順序論理回路の基本要素となるデジタル回路です。フリップフロップにはいくつかの種類があり、本記事では代表的な4種類の特徴と動作、さらに「あるフリップフロップから別のフリップフロップへ変換する」ための具体的な手順を解説します。フリップフロップには主に以下の4種類があります。SRフリップフロップDフリップフロップJKフリップフロップTフリップフロップSRフリップフロップとはSRフリップフロップは、クロック信号の立ち上がりエッジまたは立ち下がりエッジでのみ動作します。一方、SRラッチはイネーブル信号によって動作する点が異なります。SRフリップフロップの回路図を

  2. Pythonのデータ型と型変換をわかりやすく解説

    この記事では、Pythonにおける主要なデータ型の種類と、それぞれの使い方、そしてデータ型同士を変換する方法について詳しく解説します。 Pythonの組み込みデータ型一覧 Pythonでは変数を作成・宣言する際に、さまざまなデータ型を持たせることができます。Pythonには以下のような組み込みデータ型が用意されています。 str(文字列) int、float、complex(数値) list、tuple(シーケンス) dict(辞書) set(集合) bool(ブール値) bytes、bytearray(バイナリ) それでは、各データ型の特徴と作成方法を順番に見ていきましょう。 文字列型: