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


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

    Так как конфигурации компьютера могут отличаться, пример на этом шаге может или не вызывать исключение. Если вы хотите принудительно заставить исключение ввода-вывода (ввода-вывода), измените путь к папке, которая не существует на компьютере.