c++ 异常
C++是一种非常灵活的语言,但并不是非常安全。编译器允许编写改变随机内存地址或者除以0的代码(计算机无法处理无穷大)。异常就是试图增加一点安全性的语言特性。异常是一种无法预料的情形。例如,如果编写一个获取Web页面的函数,就有几件事情可能出错。包含页面的Internet主机可能被关闭,页面可能是空白的,或者连接可能会丢失。处理这种情况的一种方法是,从函数返回特定的值,如nullptr或其他错误代码。异常提供了处理此类问题的更好方法。异常伴随着一些新的术语。当某段代码检测到异常时,就会抛出一个异常。另一段代码会捕获这个异常并执行恰当的操作。下面的示例给出了一个名为divideNumbers的函数,如果调用者传递给分母的值为0,就会抛出一个异常:
double divideNumbers(double numerator, double denominator)
{
if (denominator == 0)
{
throw std::invalid_argument("Denominator cannot be 0.");
}
return numerator / denominator;
}
当执行throw行时,函数将立刻结束而不会返回值。如果调用者将函数调用放到try/catch块中, 就可以捕获异常并进行处理,如下所示:
#include <exception>
int main()
{
try
{
std::cout « divideNumbers(2.5, 0.5) « std::endl;
std::cout « divideNumbers(2.3, 0) « std::endl;
std::cout « divideNumbers(4.5, 2.5) « std::endl;
}
catch (const std::exceptions exception)
{
std::cout « "Exception caught: " << exception.what() « std::endl;
}
return 0;
}
第一次调用divideNumbers成功执行,结果会输出给用户。第二次调用会抛出一个异常,不会返回值,唯一的输出是捕获异常时输出的错误信息。第三次调用根本不会执行,因为第二次调用抛出了一个异常,导致程序跳转到catch块。前面代码块的输出是:
5
An exception was caught: Denominator cannot be 0.
C++的异常非常灵活,为正确使用异常,需要理解抛出异常时堆栈变量的行为,必须正确捕获并处理必要的异常。前面的示例中使用了内建的std::invalid_argument类型,但是最好根据所抛出的具体错误,编写自己的异常类型。与Java语言不同,C++编译器并不强制要求捕获可能发生的所有异常。如果代码从不捕获任何异常,但有异常抛出,程序自身会捕获异常并崩溃。