例外狀況: 在 3.0 版例外巨集的變更
這是進階的主題。
在 MFC 3.0 版和之後的版本中,例外處理巨集已經變更成使用 C++ 例外狀況。 這篇文章會告訴您這些變更會如何影響使用這些巨集的現有程式碼的行為。
本文涵蓋下列主題:
例外狀況型別和 CATCH 巨集
重新擲回例外狀況
例外狀況型別和 CATCH 巨集
在較早版本的 MFC 中, 攔截巨集使用 MFC 執行階段型別資訊來判斷例外狀況的型別 ; 例外狀況的類型決定,亦即,時,接收站台。 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 版因為控制項永遠會傳遞至第一個攔截具有相符的例外狀況宣告區塊。 Throw 運算式的結果
THROW( (CException*) new CCustomException() );
就會擲回為用 CException 1,即使它建構為 CCustomException。 攔截 MFC 版本 2.5 和較早的使用中的巨集CObject::IsKindOf若要在執行階段的測試類型。 因為運算式
e->IsKindOf(RUNTIME_CLASS(CException));
為 true,則第一個 catch 區塊攔截例外狀況。 在版本 3.0 中,使用 C++ 例外狀況來實作許多例外處理巨集時,擲回的第二個 catch 區塊符合CException。
就像這樣的程式碼是常見的。 它通常會顯示例外狀況物件傳遞至另一個接受泛用的函式時用 CException 1、 執行 「 預先擲回 」 處理,以及最後就會擲回例外狀況。
如果要暫時略過這個問題,將 throw 運算式從函式呼叫的程式碼,則擲回例外狀況,編譯器會產生例外狀況時已知的實際型別。
重新擲回例外狀況
Catch 區塊不能擲回相同的例外指標所捕捉。
比方說,這段程式碼是在舊版本,有效的但是會有未預期的結果與 3.0 版:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
使用擲回在 catch 區塊,會使得指標e被刪除,因此,外部接收站台將會收到不正確的指標。 Use THROW_LAST to re-throw e.
如需詳細資訊,請參閱的例外狀況: 攔截和刪除例外狀況。