📜  C++用户定义的异常(1)

📅  最后修改于: 2023-12-03 15:14:04.445000             🧑  作者: Mango

C++ 用户定义的异常

在 C++ 中,异常是异常条件的特殊情况,它可以是任何类型的数据。C++ 标准异常是内置的异常类,异常处理程序可以处理它们。

但是,在某些情况下,使用标准异常类可能会限制异常处理程序的能力,因此 C++ 允许用户定义自己的异常类。用户可以通过继承标准异常类 std::exception 来创建自己的异常类。

创建自定义异常类

下面是一个创建自定义异常类的示例,该类在被传递到异常处理程序时,将打印出错误信息。

#include <iostream>
#include <exception>

class MyException : public std::exception {
public:
    const char* what() const noexcept {
        return "My Exception occurred";
    }
};

int main() {
    try {
        throw MyException();
    } catch(MyException& e) {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

在上面的示例中,我们创建了一个名为 MyException 的异常类,该类继承自标准异常类 std::exception。类中定义了一个名为 what() 的函数,该函数返回一个包含异常消息的 const char* 类型的指针。请注意,我们的 what() 函数被 const 修饰,并且是 noexcept,因为它不会抛出异常。

接下来,在 main() 函数中,我们将 MyException 异常对象抛出,并使用 catch 块捕获异常,从而打印出异常消息。由于 MyException 继承自 std::exeption,因此异常对象将被自动转换为基类类型,从而被我们的 catch 块所捕获。

继承自标准异常类

在我们的自定义异常类中,我们可以继承自标准异常类 std::exception 或其派生类。标准异常类包括以下:

  • std::exception:它是所有标准异常类的基类,只提供了一个简单的 what() 函数。
  • std::bad_alloc:当 new 运算符无法分配所需的内存时抛出。
  • std::bad_cast:当使用 dynamic_cast 运算符失败时抛出。
  • std::runtime_error:它是由程序运行时错误引起的异常的基类。
  • std::range_error:当尝试访问超出有效范围的值时抛出。
  • std::overflow_error:当在数值溢出时抛出。
  • std::underflow_error:当在数值下溢时抛出。
  • std::logic_error:它是由逻辑错误引起的异常的基类,例如使用错误的参数调用函数。
  • std::domain_error:当使用无效的参数调用数学库函数时抛出。
  • std::invalid_argument:当使用无效的参数或参数值调用函数时抛出。
  • std::length_error:当试图创建一个超出字符串或容器的最大允许大小的对象时抛出。
  • std::out_of_range:当尝试访问超出序列范围的值时抛出。

我们可以选择继承其中一个标准异常类,或者创建一个全新的异常类。

捕获异常

在 C++ 中,异常处理程序使用 trycatch 关键字捕获异常。

try {
    // 一些可能会引发异常的代码
} catch(ExceptionType& e) {
    // 异常处理代码
} catch(...) {
    // 捕获任何类型的异常
}

在上面的示例中,我们将可能引发异常的代码放在 try 块中。如果发生异常,它将被抛出并由后面的 catch 块捕获。catch 块中的 ExceptionType 是您要捕获的异常类型,通常是您定义的自定义异常类或标准异常类。如果您不知道要捕获的异常类型,则可以使用 catch(...) 来捕获任何类型的异常。

异常的传播

当异常被抛出时,它沿着调用堆栈向上传播,直到它被传递到具有匹配 catch 块的异常处理程序为止。如果没有找到匹配的 catch 块,则程序将终止。

总结

自定义异常类可以提高程序的可读性和可维护性。当遇到异常时,您的代码将变得更加清晰和易于调试。现在,您使用 C++ 中的自定义异常类已经迈出了第一步。接下来,您可以根据自己的需求,创建更特定的异常类,并处理它们。