共用方式為


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

這是進階主題。

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

本文涵蓋下列主題:

例外狀況類型和 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 運算式的結果

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

擲回為 CException* ,即使它建構為 CCustomExceptionMFC 2.5 版和更早版本中的 CATCH 宏會使用 CObject::IsKindOf 在執行時間測試類型。 因為運算式

e->IsKindOf(RUNTIME_CLASS(CException));

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

這類程式碼並不常見。 當例外狀況物件傳遞至另一個接受泛型 CException* 的函式時,它通常會顯示,它會執行「預先擲回」處理,最後擲回例外狀況。

若要解決此問題,請將 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 區塊中使用 THROW 會導致刪除指標 e ,讓外部 catch 網站會收到不正確指標。 使用 THROW_LAST 重新擲回 e

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

另請參閱

例外狀況處理