例外狀況:釋放例外狀況中的物件
本文說明例外狀況發生時釋放物件的需求和方法。 主題包括:
架構或應用程式所擲回的例外狀況會中斷一般程式流程。 因此,請務必密切追蹤物件,以便在擲回例外狀況時正確處置物件。
有兩個主要方法可以執行這項操作。
使用
try
和catch
關鍵字在本機處理例外狀況,然後使用一個語句終結所有物件。先終結 區塊中的任何
catch
物件,再擲回區塊外部的例外狀況,以便進一步處理。
以下說明這兩種方法是下列有問題範例的解決方案:
void SomeFunc() // Problematic code
{
CPerson* myPerson = new CPerson;
// Do something that might throw an exception.
myPerson->SomeFunc();
// Now destroy the object before exiting.
// If SomeFunc above throws an exception this code will
// not be reached and myPerson will not be deleted.
delete myPerson;
}
如上 myPerson
寫,如果 擲 SomeFunc
回例外狀況,將不會刪除。 執行會直接跳至下一個外部例外狀況處理常式,略過一般函式結束和刪除物件的程式碼。 當例外狀況離開函式時,物件的指標超出範圍,只要程式正在執行,物件所佔用的記憶體就永遠不會復原。 這是記憶體流失;它會使用記憶體診斷來偵測到。
在本機處理例外狀況
try/catch 範例提供防禦性程式設計方法,可避免記憶體流失,並確保發生例外狀況時會終結您的物件。 例如,本文稍早所示的範例可能會重寫如下:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
// Handle the exception locally
e->Delete();
}
// Now destroy the object before exiting.
delete myPerson;
}
這個新範例會設定例外狀況處理常式來攔截例外狀況,並在本機處理例外狀況。 然後它會正常結束函式,並終結 物件。 此範例的重要層面是使用 try/catch 區塊建立 擷取 例外狀況的內容。 如果沒有本機例外狀況框架,函式永遠不會知道已擲回例外狀況,而且不會有機會正常結束並終結 物件。
終結物件之後擲回例外狀況
另一個處理例外狀況的方法,是將它們傳遞至下一個外部例外狀況處理內容。 在您的 catch
區塊中,您可以對本機配置的物件執行一些清除,然後擲回例外狀況以供進一步處理。
擲回函式可能或可能不需要解除配置堆積物件。 如果函式一律會在一般情況下傳回之前解除配置堆積物件,則函式也應該在擲回例外狀況之前解除配置堆積物件。 另一方面,如果函式在一般案例中傳回之前通常不會解除配置物件,則您必須根據大小寫來決定是否應該解除配置堆積物件。
下列範例示範如何清除本機配置的物件:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
e->ReportError();
// Destroy the object before passing exception on.
delete myPerson;
// Throw the exception to the next handler.
throw;
}
// On normal exits, destroy the object.
delete myPerson;
}
例外狀況機制會自動解除配置框架物件;框架物件的解構函式也會呼叫。
如果您呼叫可以擲回例外狀況的函式,您可以使用 try/catch 區塊來確保攔截例外狀況,並有機會終結您所建立的任何物件。 特別是請注意,許多 MFC 函式可能會擲回例外狀況。
如需詳細資訊,請參閱 例外狀況:攔截和刪除例外狀況 。