目录
概念
抛出异常(throw)
捕获异常(try - catch)
标准异常体系
自定义异常
多重捕获
粗略捕获
概念

异常提供了一种转移控制权的方式。
程序一旦出现没有经过处理的异常,就会造成程序运行崩溃。
异常处理机制可以帮助开发人员在程序发生异常时进行适当的处理,以确保程序可以正常执行或提供错误信息。
C++的异常处理通过使用 try 、catch 和 throw 关键字来实现。 try 块用于包含可能引发异常的代码,而 catch 块用于捕获并处理异常。 throw 关键字用于引发异常。
注意,在使用异常处理时,我们应该遵循以下几点:
- 只在真正需要时使用异常处理,不要滥用异常。
- 不要在循环或频繁调用的代码块中使用异常处理,以避免性能问题。
- 在 catch 块中应尽量提供详细的错误信息,以帮助调试和诊断问题。
抛出异常(throw)
使用 throw 关键字可以抛出异常。throw 关键字后面可以跟着一个表达式,该表达式的结果将被当作异常对象。
以下是一个示例,演示如何使用 throw 抛出异常:
double divide(double a, double b) {
if (b == 0) {
throw "Divide by zero exception";
}
return a / b;
}
在上述示例中,我们定义了一个 divide 函数,用于计算两个数的商。在函数内部,我们检查除数是否为零。如果除数为零,则使用 throw关键字抛出一个字符串异常对象。
捕获异常(try - catch)
在C++中,我们可以使用 try-catch块来捕获异常。try块用于包含可能引发异常的代码,而catch块用于处理捕获的异常。
以下是一个示例,演示如何使用try-catch捕获异常:
#include <iostream>
double divide(double a, double b) {
if (b == 0) {
throw "Divide by zero exception";
}
return a / b;
}
int main() {
try {
double result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
} catch (const char* error) {
std::cout << "Error: " << error << std::endl;
}
return 0;
}
在上述示例中,我们定义了一个divide函数,用于计算两个数的商。在函数内部,我们检查除数是否为零。如果除数为零,则使用throw关键字抛出一个字符串异常对象。
在main函数中,我们将调用divide函数放在一个try块中。如果在try块中的代码引发了异常,控制流会立即跳转到匹配的catch块,并执行其中的代码。在这个示例中,我们使用catch (const char* error)来捕获字符串异常对象,并在catch块中输出错误信息。
注意,在catch块中,我们可以使用不同类型的参数来捕获不同类型的异常对象。在上述示例中,我们使用了const char*来捕获异常对象,因为我们抛出的异常是一个字符串。
如果没有匹配的catch块来处理异常,异常将继续向上层调用栈传播,直到找到一个匹配的catch块或者到达程序的入口点(main函数)。如果一直没有找到匹配的catch块,程序将终止并显示一个未处理异常的错误消息。
标准异常体系
C++标准异常体系定义了一组异常类,用于以统一的方式处理异常情况。这些异常类都派生自基类std::exception,该基类定义了一些通用的操作和成员函数,如what()函数用于返回异常的描述信息。
class exception
{
public:
exception() _GLIBCXX_USE_NOEXCEPT { }
virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
/** Returns a C-style character string describing the general cause
* of the current error. */
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
C++标准异常体系中的异常类包括:
std::bad_alloc:内存分配失败时 抛出的异常。std::bad_cast:类型转换失败时 抛出的异常。std::bad_exception:在处理异常时 抛出的异常。std::bad_typeid:typeid操作符获取类型信息失败时 抛出的异常。std::logic_error:由程序逻辑错误 引起的异常,包括std::invalid_argument、std::domain_error、std::length_error、std::out_of_range等异常。std::runtime_error:在运行时发生的异常,包括std::range_error、std::overflow_error、std::underflow_error等异常。


自定义异常
除了以上这些标准异常类,还可以自定义异常类,只需派生自std::exception即可,需要添加头文件 #include<stdexcept> 。
一个抛出自定义异常的例子:
#include <iostream>
#include <stdexcept>
using namespace std;
class MyException :public exception
{
public:
// 覆盖what函数
// throw():异常规格说明
// 表示此函数不会出现任何异常的抛出
const char* what() const throw()
{
return "自定义类型异常";
}
};
void show(string a,string b)
{
if(a == "#" || b == "#")
{
throw MyException();
}
cout << a << b << endl;
}
int main()
{
cout << "请输入两个字符串" << endl;
string a;
string b;
cin >> a >> b;
try
{
show(a,b);
}
catch(MyException &e)
{
cout << "返回异常信息:" << e.what() << endl;
}
cout << "您输入的是:" << a << b << endl;
return 0;
}
多重捕获
在C++中,可以使用多重异常捕获来处理不同类型的异常。多重异常捕获允许在同一个try块中捕获多个不同类型的异常,并执行相应的处理操作。
多重异常捕获的语法如下所示:
try {
// 代码块
}
catch (ExceptionType1 ex) {
// 处理类型为ExceptionType1的异常
}
catch (ExceptionType2 ex) {
// 处理类型为ExceptionType2的异常
}
// 可以添加更多的catch块
catch (...) {
// 处理其他类型的异常
}
在try块中的代码可能会抛出不同类型的异常,每一个catch块都会尝试捕获指定的异常类型。当发生异常时,C++会按照catch块的顺序来匹配异常类型,如果找到匹配的catch块,则执行相应的处理操作。
请注意以下几点:
- 异常类型需要与
catch块中指定的类型相匹配,包括派生类型(多态)。 catch块的顺序很重要,应该按照从特定到一般的顺序排列。- 可以添加多个
catch块来处理不同类型的异常。 - 可以使用省略号
...来捕获其他未被前面的catch块捕获的异常,通常在最后一个catch块中使用。
通过多重异常捕获,可以灵活地处理不同类型的异常,确保程序在遇到异常时能够进行适当的处理操作。
粗略捕获
粗略异常捕获(也称为粗糙的异常处理)是通过catch块捕获异常,除了可以直接捕获异常类型外,也可以捕获异常的基类,甚至所有异常类型。粗略异常捕获使用省略号...作为异常类型,可以捕获任何类型的异常。
以下是C++中粗略异常捕获的语法:
try {
// 代码块
}
catch (...) {
// 处理所有类型的异常
}
在try块中的代码可能会抛出任何类型的异常,当发生异常时,粗略异常捕获的catch块会捕获并处理异常。您可以在catch块中执行适当的操作,如输出错误信息、记录日志或进行其他处理。
粗略异常捕获应该在某些情况下使用,例如当您希望在程序遇到任何类型的异常时都能进行某种处理时。然而,粗略异常捕获会损失异常的详细信息,因此在一般情况下,更推荐使用多重异常捕获来处理不同类型的异常,以便根据异常类型采取相应的处理方式。


![[数据集][目标检测]金属架螺栓螺丝有无检测数据集VOC+YOLO格式857张3类别](https://i-blog.csdnimg.cn/direct/9e2aff584cdc421c86ab5c2c8b97732c.png)
















