スローされた例外をキャッチすることは、関数に引数を渡すこととはまったく異なります。類似点もありますが、微妙な違いもあります。
主な違いは次の 3 つです。
- 例外は常に少なくとも 1 回はコピーされます (まったく回避することはできません)。
catch
句は、宣言された順序で検査されます (ベスト フィットではありません)。
- 型変換の対象となる形式が少なくなります。
- 継承ベースのカバー、
- 型付きポインターから型なしポインターへの変換 (
const void*
任意のポインターをキャッチします)
他の種類の変換は許可されていません (たとえばint
、 to double
、または暗黙的なconst char*
to string
- あなたの例)。
コメントの質問について
階層が存在するとします。
class Base {};
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};
句の順序に応じてcatch
、適切なブロックが実行されます。
try {
cout << "Trying ..." << endl;
throw Leaf();
} catch (Base& b) {
cout << "In Base&";
} catch (Base2& m) {
cout << "In Base2&"; //unreachable due to Base&
} catch (Derived& d) {
cout << "In Derived&"; // unreachable due to Base& and Base2&
}
順序を切り替えBase
てBase2
キャッチすると、異なる動作に気付くでしょう。Leaf
からプライベートに継承された場合Base2
、catch Base2&
どこに配置されても到達できません ( をスローすると仮定しますLeaf
)
一般的には単純です。順序が重要です。