C++ 中的异常处理
原文:https://www.studytonight.com/cpp/exception-handling-in-cpp.php
错误可以大致分为两种类型。我们将逐一讨论。
- 编译时错误
- 运行时错误
编译时错误–编译时捕获的错误称为编译时错误。编译时错误包括库引用、语法错误或不正确的类导入。
运行时错误 -它们也被称为异常。运行时捕获的异常会产生严重的问题。
错误阻碍程序的正常执行。异常处理是以不妨碍系统正常执行的方式处理错误和异常的过程。例如,用户将一个数字除以零,这将编译成功,但会出现异常或运行时错误,这将导致我们的应用程序崩溃。为了避免这种情况,我们将在代码中引入异常处理技术。
在 C++ 中,错误处理是使用三个关键字完成的:
- 尝试
- 捕捉
- 扔
语法:
try
{
//code
throw parameter;
}
catch(exceptionname ex)
{
//code to handle exception
}
try
区块
可以抛出任何异常的代码被保存在try
块中。然后,当代码将导致任何错误时,该错误/异常将被捕获在catch
块中。
catch
区块
catch
块旨在捕获错误并处理异常情况。我们可以有多个 catch 块来处理不同类型的异常,并在异常发生时执行不同的操作。例如,我们可以显示描述性消息来解释发生任何特定异常的原因。
throw
声明
它用于向异常处理程序抛出异常,即用于传递有关错误的信息。throw
表达式接受一个参数,并将该参数传递给处理程序。
throw
语句用于当我们明确希望发生异常时,那么我们可以使用throw
语句来抛出或生成该异常。
理解异常处理的需求
让我们举一个简单的例子来理解尝试、接球和投掷的用法。
下面的程序编译成功,但程序在运行时失败,导致异常。
#include <iostream>#include<conio.h>
using namespace std;
int main()
{
int a=10,b=0,c;
c=a/b;
return 0;
}
上面的程序不会运行,会在屏幕上显示运行时错误,因为我们试图用 0 除一个数,这是不可能的。
如何处理这种情况?我们可以使用异常处理来处理这种情况,并且可以通过显示一条消息来通知用户您不能将一个数字除以零。
使用try
、catch
和throw
语句
现在我们将更新上面的程序,并在其中包含异常处理。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int a=10, b=0, c;
// try block activates exception handling
try
{
if(b == 0)
{
// throw custom exception
throw "Division by zero not possible";
c = a/b;
}
}
catch(char* ex) // catches exception
{
cout<<ex;
}
return 0;
}
除以零是不可能的
在上面的代码中,我们正在检查除数,如果它为零,我们将抛出一个异常消息,然后catch
块捕获该异常并打印该消息。
这样做,用户永远不会知道我们的程序在运行时失败了,他/她只会看到“除以零不可能”的消息。
这是优雅地处理异常情况,这就是为什么使用异常处理。
使用多个catch
块
下面的程序包含多个catch
块,以不同的方式处理不同类型的异常。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int x[3] = {-1,2};
for(int i=0; i<2; i++)
{
int ex = x[i];
try
{
if (ex > 0)
// throwing numeric value as exception
throw ex;
else
// throwing a character as exception
throw 'ex';
}
catch (int ex) // to catch numeric exceptions
{
cout << "Integer exception\n";
}
catch (char ex) // to catch character/string exceptions
{
cout << "Character exception\n";
}
}
}
整数异常字符异常
上面的程序不言而喻,如果数组x
中整数的值小于 0,我们抛出一个数值作为异常,如果值大于 0,那么我们抛出一个字符值作为异常。我们有两个不同的catch
块来捕捉这些异常。
C++ 中的广义catch
块
下面的程序包含一个通用的catch
块来捕获任何未捕获的错误/异常。catch(...)
block 处理所有类型的异常。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int x[3] = {-1,2};
for(int i=0; i<2; i++)
{
int ex=x[i];
try
{
if (ex > 0)
throw ex;
else
throw 'ex';
}
// generalised catch block
catch (...)
{
cout << "Special exception\n";
}
}
return 0;
}
特殊例外特殊例外
在上面的例子中,两个异常都被一个单独的catch
块捕获。我们甚至可以有单独的catch
块来处理整数和字符异常,以及通用的catch
块。
C++ 中的标准异常
在
- std::exception -所有标准 C++ 异常的父类。
- 逻辑 _ 错误 -程序内部逻辑发生异常。
- 域 _ 错误 -使用无效域导致异常。
- 无效参数 -因无效参数导致异常。
- 超出范围 -超出范围导致异常,即大小要求超过分配。
- 长度 _ 误差 -长度误差导致异常。
- 运行时 _ 错误 -运行时发生异常。
- 范围 _ 错误 -由于内部计算中的范围错误而导致异常。
- 溢出 _ 错误 -算术溢出错误导致异常。
- 下溢 _ 错误 -由于算术下溢错误导致的异常
- bad_alloc -使用 new()分配内存失败时出现异常。
- bad_cast -动态 cast 失败时出现异常。
- bad_exception - Exception 是专门设计在动态异常说明符中列出的。
- 坏 _ type id-type id 抛出异常。