共用方式為


例外狀況:3.0 版例外狀況巨集的變更

這是進階主題。

在 MFC 3.0 版和更新版本中,例外處理巨集已改變為使用 C++ 例外狀況。 本文說明這些變更如何影響使用巨集現有程式碼的行為。

本章節涵蓋下列主題:

  • 例外狀況型別和 Catch 巨集

  • 重新擲回例外狀況

例外狀況型別和 Catch 巨集

在 MFC 舊版,CATCH 巨集使用 MFC 的執行階段型別資訊判斷例外狀況型別;也就是說,例外狀況型別是在 catch 網站決定的。 然而,有了 C++ 例外狀況,例外狀況型別永遠是在擲回網站判斷,並且是根據所擲回的例外狀況物件的型別。 這在一些罕見情況會造成不相容,像是指標對被擲回物件的型別與被擲回物件的型別不同。

下列範例說明在 MFC 3.0 版和舊版之間,這個差異的後果:

TRY
{
   THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
   TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
   TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH

這段程式碼的行為和在版本 3.0 中不同,因為控制項會傳遞具有相符例外狀況宣告的 catch 區塊。 擲回運算式的結果。

THROW( (CException*) new CCustomException() );

被擲回做為 CException*,即使它是建構為 CCustomException。 在 MFC 2.5 版和更早的版本中,CATCH 巨集使用 CObject::IsKindOf 在執行階段測試型別。 因為運算式

e->IsKindOf(RUNTIME_CLASS(CException));

為 true 時,第一個 catch 區塊攔截例外狀況。 3.0 版使用 C++ 例外狀況實作許多例外狀況處理巨集,第二個 catch 區塊符合擲回的 CException

像這樣的程式碼並不常見。 這通常會發生在例外狀況物件傳遞給接受泛型 CException* 的另一個函式,執行「處理之前擲回」,並最後擲回給例外狀況。

若要解決此問題,請將擲回運算式從函式移動至呼叫程式碼,並在產生例外狀況時擲回這個編譯器知道的實際型別的例外狀況。

重新擲回例外狀況

Catch 區塊不能擲回與它攔截的相同的例外狀況指標。

例如,這個程式碼在舊版本有效,但是在版本 3.0 會有非預期的結果:

   TRY
   {
      // Do something to throw an exception.
      AfxThrowUserException();
   }
   CATCH( CException, e )
   {
      THROW( e );    // Wrong. Use THROW_LAST() instead
   }
   END_CATCH
}

在 catch 區塊使用 THROW 蕙造成指標 e 被刪除,因此外部 catch 網站會收到無效的指標。 使用 THROW_LAST 重新擲回 e。

如需詳細資訊,請參閱 例外狀況:攔截和刪除例外狀況

請參閱

概念

MFC 中的例外狀況處理