4

C ++では、例外がスローされたためにスタックが巻き戻されているかどうかをデストラクタの本体でどのように検出できますか?検出されたら、アクティブな例外への参照を取得できますか?

特定の状況が発生する理由と、それが例外によるものかどうかを説明するデバッグコードを追加したいので、質問します。

4

4 に答える 4

7

std::uncaught_exception例外がスローされたためにスタックが巻き戻されているかどうかを示します。これはあなたが尋ねたものです。

ただし、おそらく知りたいことはわかりません。デストラクタを呼び出すオブジェクトが、スタックの一部にあるのか、スタックの一部にあるのか、それともスタックの一部にあるのか、アンワインドの一部である他のデストラクタの下のスコープを例外的に終了します。

struct A {
    ~A();
};

struct B {
    ~B();
}

int main() {
    try {
        A a;
        throw 1;
    } catch(...) {}
}

A::~A() {
    std::uncaught_exception(); // true
    B b;
}

B::~B() {
    std::uncaught_exception(); // also true, but "b" isn't being "unwound",
      // because ~A() returned, it didn't throw.
}

DeadMGとXeoの言うこととは反対に、キャッチされていない例外への参照を取得することはできません。throwオペランドがない場合、「現在処理されている例外」、つまり、キャッチハンドラーが存在する例外、またはキャッチハンドラーが呼び出した例外が再スローされます。キャッチされなかった例外は再スローされません。

于 2011-11-03T02:14:50.847 に答える
2

C ++ 17の新しいものはstd::uncaught_exceptions()どうですか?次のようなコードを作成できると思います。

class ExceptionSentinel
{
    int prev_uncaught;

public:
    ExceptionSentinel() : prev_uncaught(std::uncaught_exceptions()) {}

    ~ExceptionSentinel()
    {
        int cur_uncaught = std::uncaught_exceptions();
        if (cur_uncaught > prev_uncaught)
        {
            // ... ExceptionSentinel is being destructed by an stack unwinding process
        }
        else
        {
            // ... Normal destruction of ExceptionSentinel
        }
    }
};

この場合、std::uncaught_exceptions()コードが呼び出されるまでに、キャッチされなかった例外の数を追跡します。詳細については、cppreferenceページを参照してください。

于 2018-08-07T12:41:35.203 に答える
0

機能がありstd::uncaught_exception()ます。ただし、例外オブジェクトへのアクセスを試みるために実行できる唯一の有用なことは、それを再スローしてキャッチしようとすることです。一般に、デストラクタから例外をスローしないでください。

于 2011-11-01T13:33:16.877 に答える
-1

C ++では、例外がスローされたためにスタックが巻き戻されているかどうかをデストラクタの本体でどのように検出できますか?

いいえ。

検出されたら、アクティブな例外への参照を取得できますか?

いいえ。

于 2011-11-01T13:29:24.377 に答える