Исключения. Использование макросов 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

Дополнительные сведения см. в разделе "Исключения: изучение содержимого исключений".

См. также

Обработка исключений