Перехват исключений в Visual C++
В этой статье описывается try-catch-finally
использование блока для перехвата исключения.
Исходная версия продукта: Visual C++
Исходный номер базы знаний: 815662
Сводка
Блок try-catch-finally
— это оболочка, которая помещается вокруг любого кода, в котором может возникнуть исключение. Перехват и работа с исключениями — это стандартные задачи программирования.
Блок try-catch-finally
состоит из следующих разделов:
- Любой код, который может вызвать исключение, помещается в блок try.
- Если возникает исключение,
catch
вводится блок, и программа может выполнить соответствующую операцию для восстановления или оповещения пользователя. - Код в блоке
finally
всегда выполняется и может выполнять очистку после возникновения исключения. Блокfinally
необязателен.
В этой статье рассматриваются следующие пространства имен библиотеки классов Microsoft платформа .NET Framework: System.IO
и System.Security
.
Перехват исключений в Visual C++ .NET
Запустите Visual Studio .NET.
В меню Файл выберите пункт Создать и затем пункт Проект.
В Visual C++ щелкните Visual C++ в разделе Типы проектов, а затем выберите консольное приложение CLR в разделе Шаблоны.
В поле Имя введите Q815662 и нажмите кнопку ОК.
Замените весь код в окне кода Q815662.cpp следующим кодом. Код объявляет и инициализирует три переменные. Инициализация k вызывает ошибку.
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. }
Нажмите клавишу F5. Вы получаете
System.DivideByZeroException
исключение.try-catch
Обведите оператор вокруг кода, чтобы зафиксировать ошибку. Следующий код перехватывает все ошибки, которые возникают в коде, и отображает общее сообщение об ошибке. Замените код в окне кода Q815662.cpp следующим кодом:#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(...) { Console::WriteLine("An error occurred."); } }
Нажмите клавиши CTRL+F5, чтобы запустить приложение.
Примечание.
Сообщение об ошибке
catch
из блока отображается вместо сообщения об ошибке системного исключения.Если необходимо выполнить очистку или постобработку независимо от ошибки, используйте
__finally
часть инструкцииtry-catch-finally
. Код в последней части инструкции всегда выполняется, независимо от исключения. В следующем коде в консоли отображается следующее сообщение, даже если ошибка не произошла:This statement is always printed.
Замените код в окне кода Q815662.cpp следующим кодом:
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(...) { Console::WriteLine("An error occurred."); } __finally //This section is performed regardless of the above processing. { Console::WriteLine(); Console::WriteLine("This statement is always printed"); } }
Нажмите клавиши CTRL+F5, чтобы запустить проект.
Для получения сведений об исключении можно использовать объект исключения с оператором catch. Объект исключения имеет ряд свойств, которые могут помочь определить источник, и содержит сведения о стеке об исключении. Эта информация может быть полезной для отслеживания первоначальной причины исключения или может дать лучшее объяснение его источника. В следующем примере перехватывается исключение и выводится определенное сообщение об ошибке. Замените код в окне кода Q815662.cpp следующим кодом:
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; using namespace System::Reflection; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(Exception *e) { Console::WriteLine("An error occurred."); Console::WriteLine(e->Message); // Print the error message. Console::WriteLine(e->StackTrace); //String that contains the stack trace for this exception. } __finally //This section is performed regardless of the above processing. { Console::WriteLine(); Console::WriteLine("This statement is always printed"); } Console::ReadLine(); }
До этого момента вы работали с неспецифичным исключением. Однако если вы заранее знаете, какой тип исключения будет возникать, вы можете поймать ожидаемое исключение и обработать его соответствующим образом. Используйте несколько блоков catch, описанных в следующем коде, чтобы перехватывать все остальные исключения и работать с ними:
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; using namespace System::IO; using namespace System::Security; void _tmain(void) { try { File::Create("c:\\temp\\testapp.txt"); //Can fail for a number of resons } // This error may occur if the temp folder does not exist. catch(IOException *ioe) { Console::WriteLine("An IOException exception occurred!"); Console::WriteLine(ioe->ToString()); } // You do not have the appropriate permission to take this action. catch(SecurityException *se) { Console::WriteLine("An SecurityException exception occur") } // Catch all exceptions catch(Exception *e) { Console::WriteLine(e->ToString()); } }
Так как конфигурации компьютеров могут отличаться, пример на этом шаге может вызвать исключение или не вызвать исключение. Если вы хотите принудительно создать исключение ввода-вывода (IO), измените путь к файлу на папку, которая не существует на компьютере.