簡體   English   中英

是否檢測到由於拋出異常而析構函數何時運行?

[英]Detecting when destructor running due to exception being thrown?

在C ++中,有什么好方法可以在析構函數中檢測到它在堆棧展開期間正在運行,這是由於引發異常而不是觸發該析構函數的正常退出作用域而引起的? 我想知道,因此我可以創建一個類,其中包含一些始終在正常出口上運行但在發生異常時被跳過的清除代碼。

std::uncaught_exception() (在<exception>定義)將在析構函數中告訴您是否由於異常而調用了它:

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

也許這個文章將幫助您。 本文將向您展示std :: uncaught_exception()的問題,並包含有關如何在析構函數中處理異常的建議。

除非您有充分的理由,否則不要這樣做 堆棧展開是一種語言功能,可以強制將try塊中的所有自動對象都釋放,從而使其中的資源有機會釋放。

您希望在堆棧展開期間跳過dtor中的清除操作,這繞開了它的初衷。 而且您將冒着資源泄漏的風險。

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
  }
}

這是我可以想到的一種方法,但看起來很笨拙:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM