11

这是对为什么 Alexandrescu 不能使用 std::uncaught_exception() 在 ScopeGuard11 中实现 SCOPE_FAIL 的一种跟进?

我想检测是否有人MyClass在另一个类的析构函数中创建(或在调用堆栈中的某处使用活动的析构函数)。

class MyClass
{
public:
    MyClass(){
        assert(???what to put here????);
    }
}

void f(){
    MyClass m;    //whether this asserts should be context dependant
}

class OtherClass{
    ~OtherClass(){
        MyClass m; //this should assert
        f();       //this should too;
    }
}

int main()
{
    MyClass m;   //this should not assert
    f();         //this should also not assert
}

一种尝试可能是:

assert(!std::uncaught_exception());

但这仅在由于异常而调用析构函数时才有效,而不是因为对象超出范围而被调用时才有效。

4

2 回答 2

1

你无法检测到这一点,你也不想。这不关你的课。如果有人从 noexcept 析构函数中调用你,他会捕获异常

于 2013-02-20T00:02:40.223 回答
0

除非您让调用者提供该信息,否则您无法检测到您的函数是如何被调用的。

另外,我记得 Visual C++ 从未实现std::uncaught_exception,因此即使已知没有析构函数调用任何try块,这也将是不利的(对于可移植代码)。

但是,检测范围是否由于异常而退出是微不足道的。

只需将该范围放在try-block 中;这就是它的用途。

例如,

class Transaction
{
private:
    bool failed_;
    Transaction( Transaction const& );  // deleted
    Transaction& operator=( Transaction const& ); // deleted

public:
    void fail() { failed_ = true; }

    void commit() { ... }

    // More functionality, then

    ~Transaction()
    {
        if( failed_ ) { rollback(); }
    }

    Transaction(): failed_( false ) {}
};

void foo()
{
    Transaction transaction;

    try
    {
        // blah blah
    }
    catch( ... )
    {
         transaction.fail();
         throw;
    }
}

免责声明:我没有使用过该模式,因此无法证明它的实用性。

于 2013-02-18T18:08:08.520 回答