Обработка исключений
При выполнении программы может возникнуть ряд ненормальных условий и ошибок, называемых "исключениями". Они могут включать нехватку памяти, ошибки выделения ресурсов и сбой поиска файлов.
Библиотека классов 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:
Имя | Описание |
---|---|
AfxThrowOleDispatchException | Создает исключение в функции автоматизации OLE. |
AfxThrowOleException | Создает исключение OLE. |
Для поддержки исключений базы данных классы баз данных предоставляют два класса исключений и CDBException
CDaoException
глобальные функции для поддержки типов исключений:
Имя | Описание |
---|---|
AfxThrowDAOException | Создает CDaoException из собственного кода. |
AfxThrowDBException | Создает CDBException из собственного кода. |
MFC предоставляет следующую функцию завершения:
Имя | Описание |
---|---|
AfxAbort | Вызывается для завершения приложения при возникновении неустранимой ошибки. |
Настраивает блок 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;
}
Определяет блок кода, который перехватывает все типы исключений, создаваемые в предыдущем блоке 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
Определяет блок кода для перехвата дополнительных типов исключений, создаваемых в предыдущем блоке 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
Определяет блок кода для перехвата дополнительных типов исключений, создаваемых в предыдущем блоке 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
Помечает конец последнего блока CATCH или AND_CATCH .
END_CATCH
Дополнительные сведения о макросе END_CATCH см. в статье "Исключения".
Заголовок afx.h
Помечает конец последнего блока CATCH_ALL88 или AND_CATCH_ALL.
END_CATCH_ALL
Заголовок afx.h
Создает указанное исключение.
THROW(exception_object_pointer)
exception_object_pointer
Указывает на объект исключения, производный от CException
.
THROW прерывает выполнение программы, передав управление связанным блоком CATCH в программе. Если вы не предоставили блок CATCH , то элемент управления передается модулю библиотеки классов Microsoft Foundation, который выводит сообщение об ошибке и завершает работу.
Дополнительные сведения см. в статье "Исключения".
Заголовок afx.h
Возвращает исключение к следующему внешнему блоку CATCH .
THROW_LAST()
Этот макрос позволяет создать локально созданное исключение. Если вы попытаетесь создать исключение, которое вы только что поймали, он обычно выходит из области и удаляется. При THROW_LAST исключение передается правильно следующему обработчику CATCH .
Дополнительные сведения см. в статье "Исключения".
См. пример CFile::Abort.
Заголовок afx.h
Создает исключение архива.
void AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);
cause
Указывает целое число, указывающее причину исключения. Список возможных значений см. в разделе CArchiveException::m_cause.
lpszArchiveName
Указывает на строку, содержащую имя CArchive
объекта, вызвавшего исключение (если доступно).
Заголовок afx.h
Создает исключение файла.
void AfxThrowFileException(
int cause,
LONG lOsError = -1,
LPCTSTR lpszFileName = NULL);
cause
Указывает целое число, указывающее причину исключения. Список возможных значений см. в разделе CFileException::m_cause.
lOsError
Содержит номер ошибки операционной системы (если он доступен), который указывает причину исключения. См. руководство по операционной системе для перечисления кодов ошибок.
lpszFileName
Указывает на строку, содержащую имя файла, вызвавшего исключение (если доступно).
Вы несете ответственность за определение причины на основе кода ошибки операционной системы.
Заголовок afx.h
Вызывает недопустимое исключение аргумента.
void AfxThrowInvalidArgException( );
Эта функция вызывается при использовании недопустимых аргументов.
Заголовок: afx.h
Создает исключение памяти.
void AfxThrowMemoryException();
Вызовите эту функцию, если вызовы базовых системных распределителей памяти (например, malloc и функция GlobalAlloc Windows) завершаются сбоем. Его не нужно вызывать new
, так как new
при сбое выделения памяти создается исключение памяти автоматически.
Заголовок afx.h
Создает исключение, которое является результатом запроса на неподдерживаемую функцию.
void AfxThrowNotSupportedException();
Заголовок afx.h
Создает исключение ресурса.
void AfxThrowResourceException();
Эта функция обычно вызывается, когда не удается загрузить ресурс Windows.
Заголовок afx.h
Создает исключение для остановки операции конечного пользователя.
void AfxThrowUserException();
Эта функция обычно вызывается сразу после AfxMessageBox
сообщения об ошибке пользователю.
Заголовок afx.h
Используйте эту функцию для создания исключения в функции автоматизации 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
Создает объект типа COleException
и создает исключение.
void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);
sc
Код состояния OLE, указывающий причину исключения.
час
Обработайте код результата, указывающий причину исключения.
Версия, которая принимает HRESULT в качестве аргумента, преобразует этот результирующий код в соответствующий SCODE. Дополнительные сведения о HRESULT и SCODE см. в разделе "Структура кодов ошибок COM" в пакете SDK для Windows.
Заголовок afxdao.h
Вызовите эту функцию, чтобы вызвать исключение типа 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
Вызовите эту функцию, чтобы вызвать исключение типа 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
Функция завершения по умолчанию, предоставляемая MFC.
void AfxAbort();
AfxAbort
вызывается внутренними функциями-членами MFC, если возникает неустранимая ошибка, например неученное исключение, которое не может быть обработано. Вы можете вызвать AfxAbort
в редких случаях, когда возникает катастрофическая ошибка, из которой невозможно восстановиться.
См. пример для CATCH.
Заголовок afx.h
Макросы и глобальные
Класс CException
Класс CInvalidArgException