28

私はC++に関する本を読んでいて、エラーに関する章にこのプログラムがあります(私はいくつかのマイナーなことを省きましたが、ほとんどはこれです):

int main()
try { 
        // our program (<- this comment is literally from the book)
        return 0;
}
catch(exception& e) {
    cerr << "error: " << e.what() << '\n';
    return 1;
}
catch(...) {
    cerr << "Unknown exception\n";
    return 2;
}

これはコンパイルされましたが、もちろん何もしなかったので、私はまだ疑問に思っています

  1. main()の後にすべてを囲む中括弧のセットがないのはなぜですか?ブロックですか、それとも「キャッチフレーズ」(ha!)をmain()の一部と呼びますか?
  2. それらが関数である場合、catch(何でも)の前に「int」がないのはなぜですか?
  3. それらが機能でない場合、それらは何ですか?
  4. re catch(...)、そのように省略記号が使用されているのを見たことがありません。「何でも」を意味するためにどこでも省略記号を使用できますか?
4

6 に答える 6

16

中括弧の代わりにtryブロックを直接使用する場合、tryブロックは関数で発生するすべてのものをキャッチします。これはコンストラクターで役立ち、初期化リストで例外をキャッチできます。

これにより、barのコンストラクターからの例外がキャッチされます。

void Foo::Foo() try : bar() {
    // do something
} catch(...) {
    // do something
}

これは、本文の例外のみをキャッチします。

void Foo::Foo() : bar() {
    try {
        // do something
    } catch(...) {
        // do something
    }
}
于 2012-08-03T18:36:30.167 に答える
12

1 main()の後にすべてを囲む中括弧のセットがないのはなぜですか?..。

あり、それtryは冒頭の括弧の前にキーワードがあり、の終わりのcatchにいくつかのブロックがあります。main

...ブロックですか、それとも「キャッチフレーズ」(ha!)をmain()の一部と呼びますか?

2それらが関数である場合、catch(何でも)の前に「int」がないのはなぜですか?

3それらが機能でない場合、それらは何ですか?

それらはキーワードであり、関数ではなく、定義とその本体tryの間にあるにもかかわらず、メインの一部です。別の例については、以下の動機付けのケースを参照してください。int main(){}

4 re catch(...)、そのように省略記号が使用されているのを見たことがありません。「何でも」を意味するためにどこでも省略記号を使用できますか?

C ++には、省略記号のオーバーロードされた意味がいくつかあります。

  • catch(...)何かをキャッチすることを意味します。これは、例外タイプのワイルドカードのようなものです(複数ある場合は最後のキャッチにする必要があります)
  • int printf(char *, ...)関数が可変引数リストを受け取ることを意味します。これにより、引数の型チェックが完全に無効になり、間違えやすくなります(ただし、場合によっては便利です)。
  • template <typename... TypePack>テンプレートが変数型リストを受け入れることを意味します。これはメタプログラミングには非常に便利ですが、ここでは完全に範囲外です。
  • #define DEBUG(str, ...)可変引数関数に類似した可変個引数マクロです

関数レベルtry/catchブロックは、関数本体全体を例外ハンドラーでラップする方法です。したがって、ここでは、メインの機能ブロックはの中にありtry { ... }ます。

IIRCこれは、コンストラクターが初期化子リストをtry/catchでラップして、サブオブジェクトコンストラクターからスローされた例外を処理できるようにするために特に導入されました。

例えば。(やる気を起こさせるケース)

C::C() try : Base(1), member(2)
{ ...
}
catch (...) {
    // handle Base::Base or member construction failure here
}

初期化子リストを省略した場合でも、コンストラクター本体が開始する前に少なくともデフォルトの構築を常に行うため、基本クラスまたはメンバーのサブオブジェクトコンストラクターからスローされた例外をキャッチする他の方法はないことに注意してください。

于 2012-08-03T18:34:25.383 に答える
10

これは、この言語ではめったに使用されない機能です。try関数全体をcatchブロックで囲むことができます。

void f()
try 
{         // function starts here
...
}         // function ends here
catch (...) 
{}

この機能はほとんど役に立たないため、ほとんど使用されません。通常の関数の場合は、関数のすべてのコードをカバーするtry / catchブロックを使用できるため、この場合、この機能は必要ありません。初期化子リストで例外をキャッチできるため、コンストラクターの機能が制限されています。例外は、それ以外の場合はtry/catchブロックで囲むことはできません。

ただし、catchブロックで実行できることはほとんどないという問題があります。構築に失敗したため例外をスローする必要があります(catchブロックは、キャッチされたものとは異なる例外をスローできますが、スローする必要があります。同時に、例外がキャッチされた時点で、初期化リストのどの要素がスローされたかがわからない可能性があるため、実際にはクリーンアップを実行できません。つまり、(一般的な場合)どの要素がスローされたかがわからない可能性があります。メンバーオブジェクトが構築されているかどうか。

于 2012-08-03T18:39:01.813 に答える
2

ですfunction-try block。はい、それは合法ですが、それ以上の場合は必要ありません。説明については、この回答を参照してください。この構文の意味は何ですか?

于 2012-08-03T18:34:29.980 に答える
2

main関数の周りに中括弧がないかどうかはわかりませんが、他の人がすべて準備ができていると答えたようです。

残りの質問については、catchブロックはメインの外部の関数ではなくint、それらの前にある必要はありません。

try {}:プログラムはこのブロック内で何かを実行しようとします。何らかの理由で失敗した場合、catchブロックによってキャッチされます。

catch (exception) {}:例外がスローされると、特定のExceptionをパラメーターとして持つcatchブロックによってキャッチされ、プログラマーがそのケースを処理できるようになります。

catch (...) {}:最初のキャッチブロックを通過するものはすべてキャッチする必要があります。

于 2012-08-03T18:37:55.683 に答える
0

1)これはC ++の機能であり、関数try-catchブロック(たとえば、ここ
を参照) 2)はい、catch(...) { /* absolutely any exception gets caught here */ }

于 2012-08-03T18:35:58.753 に答える