Поделиться через


Исключения: изменения к макросам исключения в версии 3.0

Это дополнительный шаг.

В версии MFC 3,0 и более поздних, макросы обработки ошибок были изменены для использования исключений C++.Данный раздел показывает, как эти изменения могут повлиять на поведение существующего кода, использующий макросы.

Данный раздел содержит следующие подразделы.

  • Типы исключений и макрос CATCH

  • Re-бросая исключения

Типы исключений и макрос CATCH

В более ранних версиях MFC макрос CATCH использовать информацию о типах во время выполнения MFC для указания типа исключения. тип исключения определить, иначе говоря, на сайте catch.С исключениями C++, однако тип исключения всегда определяется на сайте хода типом объекта исключения, в противном случае вызывается исключение.Это приведет к несовместимости в редком случае, когда тип указателя на объект брошенному отличается от типа создание объекта.

Следующий пример иллюстрирует вследствие этого различия между версией MFC 3,0 и более ранними версиями.

TRY
{
   THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
   TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
   TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH

Этот код будет работать по-другому в версии 3.0, поскольку элемент управления всегда передает в первый блок catch с соответствующим исключение-объявлением.Результат выражения " throw

THROW( (CException*) new CCustomException() );

создает в качестве CException*, даже если он построен как CCustomException.Макрос CATCH в версиях 2.5 и более ранних CObject::IsKindOf MFC используется для проверки типа во время выполнения.Поскольку выражение

e->IsKindOf(RUNTIME_CLASS(CException));

первые объекты перехвата блока catch исключение.В версии 3.0, которая использует исключений C++ для реализации многих макросов обработки ошибок, второй блок catch соответствует брошенному CException.

Код, как это неупотребителен.Она обычно появляется, когда объект исключения передается другой функции, которая принимает универсальных CException* выполняет «pre-ход», и, наконец, создается исключение.

Обойти эту проблему, перемещение выражение хода из функции вызывающему коду и создания исключения фактического типа известного компилятору на момент исключение.

Re-Бросая исключения

Блок catch не может создавать один и тот же указатель исключения, он уловил.

Например, этот код был допустим в предыдущих версиях, но будет иметь непредвиденные результаты с версией 3.0.

   TRY
   {
      // Do something to throw an exception.
      AfxThrowUserException();
   }
   CATCH( CException, e )
   {
      THROW( e );    // Wrong. Use THROW_LAST() instead
   }
   END_CATCH
}

Использование THROW в блоке catch приводит к тому, что указатель e быть удалены, так как внешний сайт осуществляет недопустимый указатель блока catch.Используйте re-ход eTHROW_LAST.

Дополнительные сведения см. в разделе исключения: Улавливающ и удаление исключения.

См. также

Основные понятия

Обработка ошибок в MFC