Detecting when destructor running due to exception being thrown?

耗尽温柔 提交于 2019-11-29 16:32:56

问题


What is a good way in C++ to detect in a destructor that it is being run during unwind of the stack due to an exception being thrown as opposed to a normal exit of scope triggering the destructor? I'd like to know so that I can create a class that has some cleanup code that is always run on normal exit but skipped when an exception occurs.


回答1:


std::uncaught_exception() (defined in <exception>) will tell you in your destructor if it was called because of an exception:

class A
{
public:
    ~A()
    {
        if (std::uncaught_exception()) {
            // Called because of an exception
        } else {
            // No exception
        }
    }
};



回答2:


Probably this article will help you. The article will show you the problems with std::uncaught_exception() and contains an advice how to deal with exceptions in destructors.




回答3:


Don't do that unless you have a good reason. The stack unwinding is such a language feature that all automatic objects inside try block will be enforced to deallocate, so that the resources inside them have a chance to release.

You want skip cleanup in dtor during stack unwinding, which bypasses the original intention of it. And you'll run the risk of leaking resources.

Example

class CDBConnection
{
  public:
    CDBConnection()
    {
      m_db.open();
    }
    ~CDBConnection()
    {
      if (!std::uncaught_exception())
        m_db.close();

      // if this is called during a stack unwinding,
      // your DB connection will not be closed for sure.
      // That's a resource leakage.
    }
    //..
  private:
    DB m_db;
};

void main()
{
  //..
  try
  {
    // code that may throw
    CDBConnection db;
    //..        
  }
  catch(const CDBException& exp)
  {
    // properly handle the exception
  }
}



回答4:


Here is one way I can think of, but it seems clumsy:

{
  myCleanupClass unwindAction;
  try {
    // do some work which may throw exception.
  } catch (...) {
    unwindAction.disableDestructorWork();
    throw;
  }
}


来源:https://stackoverflow.com/questions/7142302/detecting-when-destructor-running-due-to-exception-being-thrown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!