throwing exceptions out of a destructor

后端 未结 16 2145
暗喜
暗喜 2020-11-22 00:23

Most people say never throw an exception out of a destructor - doing so results in undefined behavior. Stroustrup makes the point that \"the vector destructor e

16条回答
  •  粉色の甜心
    2020-11-22 01:21

    I am in the group that considers that the "scoped guard" pattern throwing in the destructor is useful in many situations - particularly for unit tests. However, be aware that in C++11, throwing in a destructor results in a call to std::terminate since destructors are implicitly annotated with noexcept.

    Andrzej Krzemieński has a great post on the topic of destructors that throw:

    • https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/

    He points out that C++11 has a mechanism to override the default noexcept for destructors:

    In C++11, a destructor is implicitly specified as noexcept. Even if you add no specification and define your destructor like this:

      class MyType {
            public: ~MyType() { throw Exception(); }            // ...
      };
    

    The compiler will still invisibly add specification noexcept to your destructor. And this means that the moment your destructor throws an exception, std::terminate will be called, even if there was no double-exception situation. If you are really determined to allow your destructors to throw, you will have to specify this explicitly; you have three options:

    • Explicitly specify your destructor as noexcept(false),
    • Inherit your class from another one that already specifies its destructor as noexcept(false).
    • Put a non-static data member in your class that already specifies its destructor as noexcept(false).

    Finally, if you do decide to throw in the destructor, you should always be aware of the risk of a double-exception (throwing while the stack is being unwind because of an exception). This would cause a call to std::terminate and it is rarely what you want. To avoid this behaviour, you can simply check if there is already an exception before throwing a new one using std::uncaught_exception().

提交回复
热议问题