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


Перехват исключений в 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

  1. Запустите Visual Studio .NET.

  2. В меню Файл выберите пункт Создать и затем пункт Проект.

  3. В Visual C++ щелкните Visual C++ в разделе Типы проектов, а затем выберите консольное приложение CLR в разделе Шаблоны.

  4. В поле Имя введите Q815662 и нажмите кнопку ОК.

  5. Замените весь код в окне кода 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.
    }
    
  6. Нажмите клавишу F5. Вы получаете System.DivideByZeroException исключение.

  7. 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.");
        }
    }
    
  8. Нажмите клавиши CTRL+F5, чтобы запустить приложение.

    Примечание.

    Сообщение об ошибке catch из блока отображается вместо сообщения об ошибке системного исключения.

  9. Если необходимо выполнить очистку или постобработку независимо от ошибки, используйте __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");
        }
    }
    
  10. Нажмите клавиши CTRL+F5, чтобы запустить проект.

  11. Для получения сведений об исключении можно использовать объект исключения с оператором 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();
    }
    
  12. До этого момента вы работали с неспецифичным исключением. Однако если вы заранее знаете, какой тип исключения будет возникать, вы можете поймать ожидаемое исключение и обработать его соответствующим образом. Используйте несколько блоков 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), измените путь к файлу на папку, которая не существует на компьютере.