在 C++ 中,异常可以分为三种主要类型:标准库异常、用户自定义异常和硬件异常。下面详细解释每一种类型,并提供一个完整的代码示例来展示如何捕获这些异常。
C++三种主要异常类型
-
标准库异常:
C++ 标准库中定义了一些异常类,如std::invalid_argument
、std::out_of_range
、std::runtime_error
等。这些异常通常由标准库函数抛出,表示函数执行过程中的错误。 -
用户自定义异常:
开发人员可以根据需要自定义异常类,以便在程序中抛出和捕获特定类型的异常。自定义异常类通常派生自std::exception
。 -
硬件异常:
这些异常通常是由硬件或操作系统引起的,比如空指针解引用、除零错误等。C++ 标准库无法捕获这些异常,但可以使用操作系统提供的机制来处理。
下面是一个完整的示例代码,展示了如何捕获以上三种类型的异常:
#include <iostream>
#include <stdexcept>
// 用户自定义异常类
class MyException : public std::exception
{
public:
const char* what() const noexcept override
{
return "My Custom Exception";
}
};
// 函数,可能会抛出异常
void foo(int x)
{
if (x == 0)
throw std::invalid_argument("x 不能为零");
if (x < 0)
throw std::out_of_range("x 不能为负数");
if (x % 2 != 0)
throw MyException();
}
int main()
{
try
{
foo(0); // 抛出 std::invalid_argument 异常
}
catch (const std::invalid_argument& e)
{
std::cerr << "Caught invalid_argument: " << e.what() << '\n';
}
catch (const std::out_of_range& e)
{
std::cerr << "Caught out_of_range: " << e.what() << '\n';
}
catch (const MyException& e)
{
std::cerr << "Caught MyException: " << e.what() << '\n';
}
catch (const std::exception& e)
{
std::cerr << "Caught generic exception: " << e.what() << '\n';
}
catch (...)
{
std::cerr << "Caught unknown exception\n";
}
try
{
int* ptr = nullptr;
*ptr = 10; // 引发空指针异常
}
catch (const std::exception& e)
{
std::cerr << "Caught exception: " << e.what() << '\n';
}
catch (...)
{
std::cerr << "Caught unknown exception\n";
}
return 0;
}
在这个示例中,foo
函数可能会抛出 std::invalid_argument
、std::out_of_range
和 MyException
异常。在 main
函数中,我们使用了 try-catch
块来捕获这些异常,并根据异常类型进行不同的处理。另外,我们也捕获了可能的硬件异常,比如空指针异常。
输出结果将根据抛出的异常类型不同而有所不同,但会显示相应的错误消息。