Undantag: Använda MFC-makron och C++-undantag

I den här artikeln beskrivs överväganden för att skriva kod som använder både MFC-undantagshanteringsmakronerna och nyckelorden för C++-undantagshantering.

Den här artikeln beskriver följande avsnitt:

Blanda undantagsnyckelord och makron

Du kan blanda MFC-undantagsmakron och C++-undantagsnyckelord i samma program. Men du kan inte blanda MFC-makron med C++-undantagsnyckelord i samma block eftersom makrona tar bort undantagsobjekt automatiskt när de hamnar utanför omfånget, medan kod som använder nyckelorden för undantagshantering inte gör det. Mer information finns i artikeln Undantag: Hantera och ta bort undantag.

Den största skillnaden mellan makrona och nyckelorden är att makrona "automatiskt" tar bort ett undantag när undantaget hamnar utanför omfånget. Kod som använder nyckelorden gör det inte; undantag som fångas i ett fångstblock måste uttryckligen raderas. Om du blandar makron och nyckelord för C++-undantag kan det orsaka minnesläckor när ett undantagsobjekt inte tas bort, eller heap-korruption då ett undantagsobjekt tas bort två gånger.

Följande kod gör till exempel undantagspekaren ogiltig:

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   throw;  // Invalid attempt to throw exception
         // to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is invalid because
   // it was deleted in the inner catch block.
}
END_CATCH

Problemet uppstår eftersom e tas bort när körningen lämnar det "inre CATCH-blocket". Om du använder THROW_LAST makro i stället för THROW-instruktionen får det "yttre" CATCH-blocket en giltig pekare:

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is valid because
   // THROW_LAST() was used.
}
END_CATCH

Prova block inuti "catch blocks"

Du kan inte återskapa det aktuella undantaget inifrån ett try block som finns i ett CATCH-block . Följande exempel är ogiltigt:

TRY
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)
{
   try
   {
      throw;  // Wrong.  Causes e (the exception 
            // being thrown) to be deleted.
   }
   catch (CException* exception)
   {
      exception->ReportError();
   }
}
END_CATCH

Mer information finns i Undantag: Undersöka undantagsinnehåll.

Se även

undantagshantering