Исключения. Использование макросов MFC и исключений C++
В этой статье рассматриваются рекомендации по написанию кода, использующего макросы обработки исключений MFC и ключевое слово обработки исключений C++.
В этой статье рассматриваются следующие темы:
Сочетание ключевых слов исключений и макросов
Макросы исключений MFC и ключевое слово исключений C++ можно смешивать в той же программе. Но нельзя смешивать макросы MFC с исключениями C++ ключевое слово в одном блоке, так как макросы автоматически удаляют объекты исключений при выходе из область, в то время как код с использованием ключевое слово обработки исключений не выполняется. Дополнительные сведения см. в статье "Исключения: перехват и удаление исключений".
Основное различие между макросами и ключевое слово заключается в том, что макросы "автоматически" удаляют заловленное исключение, когда исключение выходит из область. Код, использующий ключевое слово s, не является; исключения, пойманные в блоке catch, должны быть явно удалены. Сочетание макросов и ключевое слово исключений C++ может привести к утечке памяти при удалении объекта исключения или повреждения кучи при удалении исключения дважды.
Следующий код, например, недействителен указателем исключения:
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
Проблема возникает из-за e
удаления при выходе выполнения из блока CATCH "внутренний". Использование макроса THROW_LAST вместо инструкции THROW приведет к получению допустимого указателя "внешний" CATCH:
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
Попробовать блоки внутри блоков catch
Вы не можете повторно создать текущее исключение из try
блока, который находится внутри блока CATCH . Следующий пример недопустим:
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
Дополнительные сведения см. в разделе "Исключения: изучение содержимого исключений".