14

グローバル変数を持つことは評価されないことを私は知っています。しかし、BjarneStroustrupによる本C++プログラミング言語では、著者は「非ローカル静的オブジェクトの初期化子からスローされた場合に制御を取得する唯一の方法はset_unexpected()です」と述べています。それはどのように行われますか?

4

2 に答える 2

8

他のフォーラムに質問を投稿し、いくつかの回答を得ました。

最初の 1 つは、オブジェクトを持つのではなくポインターを宣言し、main() で初期化することでした。

2 つ目は、意味のあるハンドラーを設定するために set_terminate を実行する別のクラスから (そのコンストラクターが例外をスローする) クラスを派生させることでした。2 つ目は codeblocks ide で問題なく動作するようです。

テストチェックに使用したコードは次のとおりです。

void f()        //Unexpected exception handler
{
    cout<<"Terminate called "<<endl;
    exit (0);
}
class A         //Base class that performs set_unexpected
{
    terminate_handler h;
public:
    A()
    {
        h=set_terminate(f);
    }
    ~A()
    {
        set_terminate(h);
    }
};
class B:public A    //Derived class that throws unexpected_exception
{
public:
    B()
    {
        throw 1;
    }
};
B b;
int main()
{
}

プログラムはメッセージ「Terminate called」を表示して終了します。

于 2012-12-12T13:10:34.900 に答える
0

try/catchブロックは関数スコープ内または関数スコープと一緒です。したがって、グローバル オブジェクトはtry/catchスコープ内に存在できないため、これらの例外をキャッチすることはできません。

try/catch特別な構文を調べることができます:

class Test {
public:
  Test ()
  try { throw 0; }
  catch(...) {}
};

これにより、そのような例外の処理がいくらか緩和されます。ここに同じことを議論している1つのスレッドがあります。
ただし、グローバルオブジェクトを宣言するすべてのクラスにそのような構文を提供する必要があります

try/catchコンストラクター自体の中に入れた場合の違いは何だろうと思うかもしれません。グローバル オブジェクトの初期化に失敗すると、内部オブジェクトがtry/catch黙ってそれを吸収しますが、これは悪いことです。
しかし、上記の構文は、エラー診断の機会を与えてから、プログラムを終了させる例外を再度スローします。
詳細については、このスレッドを参照してください。

一方、スローされた例外にstd::unexpected()適切なものがない場合に呼び出されます。catch()この機能は標準ですが、 を使用して独自に構成できますstd::set_unexpected()

于 2012-12-06T05:16:02.090 に答える