我们使用异常处理来系统地克服程序执行过程中发生的异常。
将数字除以零是一个数学错误(未定义),我们可以使用异常处理来优雅地克服此类操作。如果您在不使用异常处理的情况下编写代码,那么被零除的输出将显示为无穷大,无法进一步处理。
考虑下面给出的代码,除法函数返回分子除以分母的结果,该结果存储在主变量结果中,然后显示。该除法函数对于分母为零没有任何要求。
// Program to show division without using
// Exception Handling
#include
using namespace std;
// Defining function Division
float Division(float num, float den)
{
// return the result of division
return (num / den);
} // end Division
int main()
{
// storing 12.5 in numerator
// and 0 in denominator
float numerator = 12.5;
float denominator = 0;
float result;
// calls Division function
result = Division(numerator, denominator);
// display the value stored in result
cout << "The quotient of 12.5/0 is "
<< result << endl;
} // end main
The quotient of 12.5/0 is inf
我们可以通过多种不同的方式处理此异常,以下列出了其中的一些方式
- 1)使用runtime_error类
runtime_error类是标准库类异常的派生类,在异常头文件中定义,用于表示运行时错误。
现在,我们考虑完全相同的代码,但包括以零可能性处理除法的代码。在这里,我们在main内部有一个try块,它调用Division函数。除法函数检查传递的分母是否等于零(如果否,则返回商),如果是,则抛出runtime_error异常。该异常由catch块捕获,该块打印消息“发生异常”,然后使用runtime_error对象e调用what函数。 what()函数(在下面的代码中使用)是stdexcept头文件中定义的Standard异常类的虚函数,用于标识异常。这将打印消息“数学错误:试图除以零”,此后程序将恢复普通的指令序列。// Program to depict how to handle // divide by zero exception #include
#include // To use runtime_error using namespace std; // Defining function Division float Division(float num, float den) { // If denominator is Zero // throw runtime_error if (den == 0) { throw runtime_error("Math error: Attempted to divide by Zero\n"); } // Otherwise return the result of division return (num / den); } // end Division int main() { float numerator, denominator, result; numerator = 12.5; denominator = 0; // try block calls the Division function try { result = Division(numerator, denominator); // this will not print in this example cout << "The quotient is " << result << endl; } // catch block catches exception thrown // by the Division function catch (runtime_error& e) { // prints that exception has occurred // calls the what function // using runtime_error object cout << "Exception occurred" << endl << e.what(); } } // end main 输出:Exception occurred Math error: Attempted to divide by Zero
- 2)使用用户定义的异常处理
在这里,我们定义了一个Exception类,该类从runtime_error类公开继承。在类Exception的内部,我们仅定义一个构造函数,该构造函数在使用类对象调用时将显示消息“数学错误:试图除以零”。当分母为零时,我们定义除法函数,该函数调用Exception类的构造函数,否则返回商。在main内部,我们给分子和分母分别赋值12.5和0。然后我们进入try块,该块调用Division函数,该函数将返回商或引发异常。 catch块捕获Exception类型的异常,显示消息“发生异常”,然后调用what函数。处理异常后,程序将恢复。
// Program to depict user defined exception handling #include
#include // For using runtime_error using namespace std; // User defined class for handling exception // Class Exception publicly inherits // the runtime_error class class Exception : public runtime_error { public: // Defining constructor of class Exception // that passes a string message to the runtime_error class Exception() : runtime_error("Math error: Attempted to divide by Zero\n") { } }; // defining Division function float Division(float num, float den) { // If denominator is Zero // throw user defined exception of type Exception if (den == 0) throw Exception(); // otherwise return the result of division return (num / den); } // end Division int main() { float numerator, denominator, result; numerator = 12.5; denominator = 0; // try block calls the Division function try { result = Division(numerator, denominator); // this will not print in this example cout << "The quotient is " << result << endl; } // catch block catches exception if any // of type Exception catch (Exception& e) { // prints that exception has occurred // calls the what function using object of // the user defined class called Exception cout << "Exception occurred" << endl << e.what(); } } // end main 输出:Exception occurred Math error: Attempted to divide by Zero
- 3)使用堆栈展开
在堆栈展开中,我们有一个主要的内部,try块调用Division函数,而Division函数依次调用CheckDenominator函数。 CheckDenominator函数检查分母是否为零,如果为true,则引发异常,否则返回分母的值。除法函数计算商的值(如果传递了分母的非零值)并将其返回给主函数。 catch块捕获抛出的所有异常,并显示消息“发生异常”,并调用显示“ Math error:试图除以零的数学错误”的what函数。此后,程序将恢复。
// Program to depict Exception Handling // Using stack unwinding #include
#include using namespace std; // defining the CheckDenominator function float CheckDenominator(float den) { // if denominator is zero // throw exception if (den == 0) { throw runtime_error("Math error: Attempted to divide by zero\n"); } else return den; } // end CheckDenominator // defining Division function float Division(float num, float den) { // Division function calls CheckDenominator return (num / CheckDenominator(den)); } // end Division int main() { float numerator, denominator, result; numerator = 12.5; denominator = 0; // try block calls the Division function try { result = Division(numerator, denominator); // This will not print in this example cout << "The quotient is " << result << endl; } // catch block catches exception if any catch (runtime_error& e) { // prints that exception has occurred // calls the what function using object of // runtime_error class cout << "Exception occurred" << endl << e.what(); } } // end main 输出:Exception occurred Math error: Attempted to divide by zero
- 4)使用try and catch(…)
在此代码中,try块调用CheckDenominator函数。在CheckDenominator函数,我们检查分母是否为零,如果为true,则通过传递字符串“ Error”引发异常。该字符串由catch块捕获,因此输出消息“发生异常”。这里的catch块能够捕获任何类型的异常。
// Program to depict use of try catch block #include
#include using namespace std; // defining CheckDenominator float CheckDenominator(float den) { if (den == 0) throw "Error"; else return den; } // end CheckDenominator int main() { float numerator, denominator, result; numerator = 12.5; denominator = 0; // try block try { // calls the CheckDenominator function // by passing a string "Error" if (CheckDenominator(denominator)) { result = (numerator / denominator); cout << "The quotient is " << result << endl; } } // catch block // capable of catching any type of exception catch (...) { // Display a that exception has occurred cout << "Exception occurred" << endl; } } // end main 输出:Exception occurred