Výjimky: Použití výjimek v makrech MFC a jazyce C++
Tento článek popisuje aspekty psaní kódu, který používá makra zpracování výjimek MFC i klíčová slova zpracování výjimek jazyka C++.
Tento článek se zabývá následujícími tématy:
Kombinování klíčových slov výjimek a maker
Makra výjimek MFC a klíčová slova výjimek jazyka C++ můžete kombinovat ve stejném programu. Makra MFC s klíčovými slovy výjimek jazyka C++ však nelze kombinovat ve stejném bloku, protože makra odstraňují objekty výjimek automaticky, když přejdou mimo rozsah, zatímco kód využívající klíčová slova zpracování výjimek ne. Další informace najdete v článku Výjimky: Zachytávání a odstraňování výjimek.
Hlavním rozdílem mezi makry a klíčovými slovy je, že makra "automaticky" odstraní zachycenou výjimku, když výjimka zmizí z oboru. Kód využívající klíčová slova ne; Výjimky zachycené v bloku catch musí být explicitně odstraněny. Kombinování maker a klíčových slov výjimek jazyka C++ může způsobit nevracení paměti, pokud objekt výjimky není odstraněn, nebo poškození haldy při odstranění výjimky dvakrát.
Následující kód například zneplatní ukazatel výjimky:
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
K tomuto problému dochází, protože e
je odstraněn, když provádění projde z "vnitřní" CATCH bloku. Použití makra THROW_LAST místo příkazu THROW způsobí, že "vnější" blok CATCH obdrží platný ukazatel:
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
Vyzkoušet bloky uvnitř bloků catch
Aktuální výjimku nelze znovu vyvolat z try
bloku, který je uvnitř bloku CATCH . Následující příklad je neplatný:
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
Další informace naleznete v tématu Výjimky: Zkoumání obsahu výjimky.