本文介绍如何使用 try-catch-finally
块捕获异常。
原始产品版本: Visual C++
原始 KB 数: 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++ 中,单击“项目类型”下的“视觉对象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)异常,请将文件路径更改为计算机上不存在的文件夹。