在 Visual C++ 中捕获异常

本文介绍如何使用 try-catch-finally 块捕获异常。

原始产品版本: Visual C++
原始 KB 数: 815662

总结

try-catch-finally 是一个包装器,可在发生异常的任何代码周围放置。 捕获和处理异常是标准编程任务。

try-catch-finally 由以下部分组成:

  • 可能引发异常的任何代码都放置在 try 块中。
  • 如果引发异常, catch 则输入块,程序可以执行相应的操作来恢复或提醒用户。
  • 始终执行块中的 finally 代码,可以在发生异常后进行清理。 块 finally 是可选的。

本文介绍以下Microsoft .NET Framework 类库命名空间: System.IOSystem.Security

捕获 Visual C++ .NET 中的异常

  1. 启动 Visual Studio .NET。

  2. “文件” 菜单上,指向 “新建” ,然后单击 “项目”

  3. 在 Visual C++ 中,单击“项目类型”下的“视觉对象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)异常,请将文件路径更改为计算机上不存在的文件夹。