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

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

Библиотека классов Microsoft Foundation использует схему обработки исключений, которая моделировалась тесно после того, как она была предложена комитетом по стандартам ANSI для C++. Перед вызовом функции, которая может столкнуться с ненормальной ситуацией, необходимо настроить обработчик исключений. Если функция сталкивается с ненормальным условием, она вызывает исключение и элемент управления передается обработчику исключений.

Несколько макросов, включенных в библиотеку классов Microsoft Foundation, настроят обработчики исключений. Ряд других глобальных функций помогает создавать специализированные исключения и завершать программы при необходимости. Эти макросы и глобальные функции делятся на следующие категории:

  • Макросы исключений, которые структурирует обработчик исключений.

  • Функции создания исключений), которые создают исключения определенных типов.

  • Функции завершения, которые вызывают завершение программы.

Примеры и дополнительные сведения см. в статье "Исключения".

Макросы исключений

Имя Описание
ПОПРОБОВАТЬ Задает блок кода для обработки исключений.
ПОЙМАТЬ Задает блок кода для перехвата исключения из предыдущего блока TRY .
CATCH_ALL Задает блок кода для перехвата всех исключений из предыдущего блока TRY .
AND_CATCH Задает блок кода для перехвата дополнительных типов исключений из предыдущего блока TRY .
AND_CATCH_ALL Задает блок кода для перехвата всех других дополнительных типов исключений, создаваемых в предыдущем блоке TRY .
END_CATCH Заканчивает последний блок кода CATCH или AND_CATCH .
END_CATCH_ALL Заканчивает последний блок кода CATCH_ALL .
THROW Создает указанное исключение.
THROW_LAST Вызывает исключение, обработанное в данный момент, для следующего внешнего обработчика.

Функции, вызываемые исключениями

Имя Описание
AfxThrowArchiveException Создает исключение архива.
AfxThrowFileException Создает исключение файла.
AfxThrowInvalidArgException Вызывает недопустимое исключение аргумента.
AfxThrowMemoryException Создает исключение памяти.
AfxThrowNotSupportedException Создает исключение, не поддерживаемое.
AfxThrowResourceException Создает исключение, не найденное ресурсом Windows.
AfxThrowUserException Создает исключение в действии программы, инициированной пользователем.

MFC предоставляет две функции создания исключений специально для исключений OLE:

Функции исключений OLE

Имя Описание
AfxThrowOleDispatchException Создает исключение в функции автоматизации OLE.
AfxThrowOleException Создает исключение OLE.

Для поддержки исключений базы данных классы баз данных предоставляют два класса исключений и CDBExceptionCDaoExceptionглобальные функции для поддержки типов исключений:

Функции исключений DAO

Имя Описание
AfxThrowDAOException Создает CDaoException из собственного кода.
AfxThrowDBException Создает CDBException из собственного кода.

MFC предоставляет следующую функцию завершения:

Функции завершения

Имя Описание
AfxAbort Вызывается для завершения приложения при возникновении неустранимой ошибки.

TRY

Настраивает блок TRY .

TRY

Замечания

Блок TRY определяет блок кода, который может вызывать исключения. Эти исключения обрабатываются в следующих блоках CATCH и AND_CATCH . Допускается рекурсия: исключения могут передаваться во внешний блок TRY , игнорируя их или используя макрос THROW_LAST. Завершите блок TRY END_CATCH или макросом END_CATCH_ALL.

Дополнительные сведения см. в статье "Исключения".

Пример

См. пример для CATCH.

Требования

Заголовок: afx.h

ПОЙМАТЬ

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

CATCH(exception_class, exception_object_pointer_name)

Параметры

exception_class
Указывает тип исключения для тестирования. Список стандартных классов исключений см. в разделе CException класса.

exception_object_pointer_name
Задает имя указателя на объект исключения, который будет создан макросом. Имя указателя можно использовать для доступа к объекту исключения в блоке CATCH . Эта переменная объявлена для вас.

Замечания

Код обработки исключений может провести допрос объекта исключения( при необходимости), чтобы получить дополнительные сведения о конкретной причине исключения. Вызовите макрос THROW_LAST, чтобы перейти к следующему внешнему кадру исключений. Завершите блок TRY с помощью макроса END_CATCH.

Если exception_class является классом CException, все типы исключений будут пойманы. Функцию-член CObject::IsKindOf можно использовать для определения конкретного исключения. Лучший способ перехвата нескольких видов исключений — использовать последовательные операторы AND_CATCH , каждый из которых имеет другой тип исключения.

Указатель объекта исключения создается макросом. Вам не нужно объявлять это самостоятельно.

Примечание.

Блок CATCH определяется как область C++, очерченный фигурными скобками. Если вы объявляете переменные в этом область, они доступны только в пределах этого область. Это также относится к exception_object_pointer_name.

Дополнительные сведения об исключениях и макросе CATCH см. в статье "Исключения".

Пример

CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
TRY
{
   pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
      CFile::modeRead | CFile::shareDenyNone);
   ULONGLONG dwLength = pFile->GetLength();
   CString str;
   str.Format(_T("Your SYSTEM.INI file is %I64u bytes long.") , dwLength);
   AfxMessageBox(str);
}
CATCH(CFileException, pEx)
{
   // Simply show an error message to the user.
   pEx->ReportError();
}
AND_CATCH(CMemoryException, pEx)
{
   // We can't recover from this memory exception, so we'll
   // just terminate the app without any cleanup. Normally, 
   // an application should do everything it possibly can to
   // clean up properly and not call AfxAbort().
   AfxAbort();
}
END_CATCH
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our cleanup code needs to test for NULL.
if (pFile != NULL)
{
   pFile->Close();
   delete pFile;
}

CATCH_ALL

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

CATCH_ALL(exception_object_pointer_name)

Параметры

exception_object_pointer_name
Задает имя указателя на объект исключения, который будет создан макросом. Для доступа к объекту исключения в CATCH_ALL блоке можно использовать имя указателя. Эта переменная объявлена для вас.

Замечания

Код обработки исключений может провести допрос объекта исключения( при необходимости), чтобы получить дополнительные сведения о конкретной причине исключения. THROW_LAST Вызовите макрос, чтобы переместить обработку на следующий внешний кадр исключений. Если вы используете CATCH_ALL, завершите блок TRY с помощью макроса END_CATCH_ALL.

Примечание.

Блок CATCH_ALL определяется как область C++, очерченный фигурными скобками. Если вы объявляете переменные в этом область, они доступны только в пределах этого область.

Дополнительные сведения об исключениях см. в статье "Исключения".

Пример

См. пример CFile::Abort.

Требования

Заголовок afx.h

AND_CATCH

Определяет блок кода для перехвата дополнительных типов исключений, создаваемых в предыдущем блоке TRY .

AND_CATCH(exception_class, exception_object_pointer_name)

Параметры

exception_class
Указывает тип исключения для тестирования. Список стандартных классов исключений см. в разделе CException класса.

exception_object_pointer_name
Имя указателя на объект исключения, который будет создан макросом. Имя указателя можно использовать для доступа к объекту исключения в блоке AND_CATCH . Эта переменная объявлена для вас.

Замечания

Используйте макрос CATCH для перехвата одного типа исключения, а затем макрос AND_CATCH для перехвата каждого последующего типа. Завершите блок TRY с помощью макроса END_CATCH.

Код обработки исключений может провести допрос объекта исключения( при необходимости), чтобы получить дополнительные сведения о конкретной причине исключения. Вызовите макрос THROW_LAST в блоке AND_CATCH , чтобы переместить обработку на следующий внешний кадр исключений. AND_CATCH помечает конец предыдущего блока CATCH или AND_CATCH.

Примечание.

Блок AND_CATCH определяется как область C++ (отложенный фигурными скобками). Если вы объявляете переменные в этом область, помните, что они доступны только в рамках этого область. Это также относится к переменной exception_object_pointer_name .

Пример

См. пример для CATCH.

Требования

Заголовок afx.h

AND_CATCH_ALL

Определяет блок кода для перехвата дополнительных типов исключений, создаваемых в предыдущем блоке TRY .

AND_CATCH_ALL(exception_object_pointer_name)

Параметры

exception_object_pointer_name
Имя указателя на объект исключения, который будет создан макросом. Имя указателя можно использовать для доступа к объекту исключения в блоке AND_CATCH_ALL . Эта переменная объявлена для вас.

Замечания

Используйте макрос CATCH для перехвата одного типа исключения, а затем макрос AND_CATCH_ALL для перехвата всех остальных последующих типов. Если вы используете AND_CATCH_ALL, завершите блок TRY с помощью макроса END_CATCH_ALL.

Код обработки исключений может провести допрос объекта исключения( при необходимости), чтобы получить дополнительные сведения о конкретной причине исключения. Вызовите макрос THROW_LAST в блоке AND_CATCH_ALL , чтобы переместить обработку на следующий внешний кадр исключений. AND_CATCH_ALL помечает конец предыдущего блока CATCH или AND_CATCH_ALL.

Примечание.

Блок AND_CATCH_ALL определяется как область C++ (очертаются фигурными скобками). Если вы объявляете переменные в этом область, помните, что они доступны только в рамках этого область.

Требования

Заголовок afx.h

END_CATCH

Помечает конец последнего блока CATCH или AND_CATCH .

END_CATCH

Замечания

Дополнительные сведения о макросе END_CATCH см. в статье "Исключения".

Требования

Заголовок afx.h

END_CATCH_ALL

Помечает конец последнего блока CATCH_ALL88 или AND_CATCH_ALL.

END_CATCH_ALL

Требования

Заголовок afx.h

THROW (MFC)

Создает указанное исключение.

THROW(exception_object_pointer)

Параметры

exception_object_pointer
Указывает на объект исключения, производный от CException.

Замечания

THROW прерывает выполнение программы, передав управление связанным блоком CATCH в программе. Если вы не предоставили блок CATCH , то элемент управления передается модулю библиотеки классов Microsoft Foundation, который выводит сообщение об ошибке и завершает работу.

Дополнительные сведения см. в статье "Исключения".

Требования

Заголовок afx.h

THROW_LAST

Возвращает исключение к следующему внешнему блоку CATCH .

THROW_LAST()

Замечания

Этот макрос позволяет создать локально созданное исключение. Если вы пытаетесь вызвать исключение, которое вы только что поймали, он обычно выходит из область и удаляется. При THROW_LAST исключение передается правильно следующему обработчику CATCH .

Дополнительные сведения см. в статье "Исключения".

Пример

См. пример CFile::Abort.

Требования

Заголовок afx.h

AfxThrowArchiveException

Создает исключение архива.

void  AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);

Параметры

cause
Указывает целое число, указывающее причину исключения. Список возможных значений см. в разделе CArchiveException::m_cause.

lpszArchiveName
Указывает на строку, содержащую имя CArchive объекта, вызвавшего исключение (если доступно).

Требования

Заголовок afx.h

AfxThrowFileException

Создает исключение файла.

void AfxThrowFileException(
    int cause,
    LONG lOsError = -1,
    LPCTSTR lpszFileName = NULL);

Параметры

cause
Указывает целое число, указывающее причину исключения. Список возможных значений см. в разделе CFileException::m_cause.

lOsError
Содержит номер ошибки операционной системы (если он доступен), который указывает причину исключения. См. руководство по операционной системе для перечисления кодов ошибок.

lpszFileName
Указывает на строку, содержащую имя файла, вызвавшего исключение (если доступно).

Замечания

Вы несете ответственность за определение причины на основе кода ошибки операционной системы.

Требования

Заголовок afx.h

AfxThrowInvalidArgException

Вызывает недопустимое исключение аргумента.

Синтаксис

void AfxThrowInvalidArgException( );

Замечания

Эта функция вызывается при использовании недопустимых аргументов.

Требования

Заголовок: afx.h

AfxThrowMemoryException

Создает исключение памяти.

void AfxThrowMemoryException();

Замечания

Вызовите эту функцию, если вызовы базовых системных распределителей памяти (например, malloc и функция GlobalAlloc Windows) завершаются сбоем. Его не нужно вызывать new , так как new при сбое выделения памяти создается исключение памяти автоматически.

Требования

Заголовок afx.h

AfxThrowNotSupportedException

Создает исключение, которое является результатом запроса на неподдерживаемую функцию.

void AfxThrowNotSupportedException();

Требования

Заголовок afx.h

AfxThrowResourceException

Создает исключение ресурса.

void  AfxThrowResourceException();

Замечания

Эта функция обычно вызывается, когда не удается загрузить ресурс Windows.

Требования

Заголовок afx.h

AfxThrowUserException

Создает исключение для остановки операции конечного пользователя.

void AfxThrowUserException();

Замечания

Эта функция обычно вызывается сразу после AfxMessageBox сообщения об ошибке пользователю.

Требования

Заголовок afx.h

AfxThrowOleDispatchException

Используйте эту функцию для создания исключения в функции автоматизации OLE.

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode ,
    LPCSTR lpszDescription,
    UINT nHelpID = 0);

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode,
    UINT nDescriptionID,
    UINT nHelpID = -1);

Параметры

wCode
Код ошибки, характерный для приложения.

lpszDescription
Словесное описание ошибки.

nDescriptionID
Идентификатор ресурса для описания словесной ошибки.

nHelpID
Контекст справки для справки приложения (. Файл HLP.

Замечания

Сведения, предоставленные этой функции, могут отображаться приложением для вождения (Microsoft Visual Basic или другим клиентским приложением автоматизации OLE).

Пример

// Sort is method of automation class CStrArrayDoc
long CStrArrayDoc::Sort(VARIANT* vArray)
{
   USES_CONVERSION;

   // Type check VARIANT parameter. It should contain a BSTR array
   // passed by reference. The array must be passed by reference; it is
   // an in-out-parameter.

   // throwing COleDispatchException allows the EXCEPINFO structure of 
   // IDispatch::Invoke() to set
   if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
      AfxThrowOleDispatchException(1001,
         _T("Type Mismatch in Parameter. Pass a string array by reference"));

   // ...
   // ...

   return 0;
}

Требования

Заголовок afx.h

AfxThrowOleException

Создает объект типа COleException и создает исключение.

void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);

Параметры

Sc
Код состояния OLE, указывающий причину исключения.

Hr
Обработайте код результата, указывающий причину исключения.

Замечания

Версия, которая принимает HRESULT в качестве аргумента, преобразует этот результирующий код в соответствующий SCODE. Дополнительные сведения о HRESULT и SCODE см. в разделе "Структура кодов ошибок COM" в пакете SDK для Windows.

Требования

Заголовок afxdao.h

AfxThrowDaoException

Вызовите эту функцию, чтобы вызвать исключение типа CDaoException из собственного кода.

void AFXAPI AfxThrowDaoException(
    int nAfxDaoError = NO_AFX_DAO_ERROR,
    SCODE scode = S_OK);

Параметры

nAfxDaoError
Целочисленное значение, представляющее расширенный код ошибки DAO, которое может быть одним из значений, перечисленных в разделе CDaoException::m_nAfxDaoError.

scode
Код ошибки OLE из DAO типа SCODE. Дополнительные сведения см. в разделе CDaoException::m_scode.

Замечания

Платформа также вызывает AfxThrowDaoException. В вызове можно передать один из параметров или обоих. Например, если вы хотите вызвать одну из ошибок, определенных в CDaoException::nAfxDaoError , но не заботитесь о параметре scode , передайте допустимый код в параметре nAfxDaoError и примите значение по умолчанию для кода.

Сведения об исключениях, связанных с классами DAO MFC, см. в этой CDaoException книге, а также в статье "Исключения базы данных".

Требования

Заголовок afxdb.h

AfxThrowDBException

Вызовите эту функцию, чтобы вызвать исключение типа CDBException из собственного кода.

void AfxThrowDBException(
    RETCODE nRetCode,
    CDatabase* pdb,
    HSTMT hstmt);

Параметры

nRetCode
Значение типа RETCODE, определяющее тип ошибки, вызвавшей исключение.

Pdb
Указатель на CDatabase объект, представляющий соединение источника данных, с которым связано исключение.

hstmt
Дескриптор ODBC HSTMT, указывающий дескриптор оператора, с которым связано исключение.

Замечания

Платформа вызывается AfxThrowDBException при получении ODBC RETCODE из вызова функции API ODBC и интерпретирует RETCODE как исключительное условие, а не ожидаемую ошибку. Например, операция доступа к данным может завершиться ошибкой из-за ошибки чтения диска.

Сведения о значениях RETCODE, определенных ODBC, см. в главе 8 "Получение сведений о состоянии и ошибке" в пакете SDK для Windows. Сведения о расширениях MFC для этих кодов см. в разделе CDBException класса.

Требования

Заголовок afx.h

AfxAbort

Функция завершения по умолчанию, предоставляемая MFC.

void  AfxAbort();

Замечания

AfxAbort вызывается внутренними функциями-членами MFC, если возникает неустранимая ошибка, например неученное исключение, которое не может быть обработано. Вы можете вызвать AfxAbort в редких случаях, когда возникает катастрофическая ошибка, из которой невозможно восстановиться.

Пример

См. пример для CATCH.

Требования

Заголовок afx.h

См. также

Макросы и глобальные
Класс CException
Класс CInvalidArgException