📅  最后修改于: 2020-12-17 05:14:17             🧑  作者: Mango
例外是在程序执行期间出现的问题。 C++异常是对程序运行时出现的异常情况的一种响应,例如试图除以零。
异常提供了一种将控制权从程序的一部分转移到另一部分的方法。 C++异常处理基于三个关键字构建: try,catch和throw 。
throw-问题出现时,程序将引发异常。这是使用throw关键字完成的。
catch-程序在要处理问题的程序中的某个位置使用异常处理程序捕获异常。 catch关键字指示捕获异常。
try – try块标识将为其激活特定异常的代码块。随后是一个或多个捕获块。
假设一个块将引发异常,则一种方法使用try和catch关键字的组合来捕获异常。在可能产生异常的代码周围放置了一个try / catch块。 try / catch块中的代码称为受保护的代码,使用try / catch的语法如下-
try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}
您可以列出多个catch语句以捕获不同类型的异常,以防在不同情况下try块引发多个异常。
可以使用throw语句在代码块内的任何位置抛出异常。 throw语句的操作数确定异常的类型,可以是任何表达式,表达式结果的类型确定抛出的异常的类型。
以下是发生除以零的条件时引发异常的示例-
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
try块之后的catch块捕获任何异常。您可以指定要捕获的异常类型,这取决于关键字catch后面括号中的异常声明。
try {
// protected code
} catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
上面的代码将捕获ExceptionName类型的异常。如果要指定catch块应处理在try块中引发的任何类型的异常,则必须在包含异常声明的括号之间放置省略号…,如下所示-
try {
// protected code
} catch(...) {
// code to handle any exception
}
以下是一个示例,该示例引发了一个被零除的异常,我们将其捕获在catch块中。
#include
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
} catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
因为我们引发了const char *类型的异常,所以在捕获此异常时,我们必须在catch块中使用const char *。如果我们编译并运行以上代码,这将产生以下结果-
Division by zero condition!
C++提供了在
这是上述层次结构中提到的每个异常的简短描述-
Sr.No | Exception & Description |
---|---|
1 |
std::exception An exception and parent class of all the standard C++ exceptions. |
2 |
std::bad_alloc This can be thrown by new. |
3 |
std::bad_cast This can be thrown by dynamic_cast. |
4 |
std::bad_exception This is useful device to handle unexpected exceptions in a C++ program. |
5 |
std::bad_typeid This can be thrown by typeid. |
6 |
std::logic_error An exception that theoretically can be detected by reading the code. |
7 |
std::domain_error This is an exception thrown when a mathematically invalid domain is used. |
8 |
std::invalid_argument This is thrown due to invalid arguments. |
9 |
std::length_error This is thrown when a too big std::string is created. |
10 |
std::out_of_range This can be thrown by the ‘at’ method, for example a std::vector and std::bitset<>::operator[](). |
11 |
std::runtime_error An exception that theoretically cannot be detected by reading the code. |
12 |
std::overflow_error This is thrown if a mathematical overflow occurs. |
13 |
std::range_error This is occurred when you try to store a value which is out of range. |
14 |
std::underflow_error This is thrown if a mathematical underflow occurs. |
您可以通过继承和覆盖异常类功能来定义自己的异常。以下是示例,显示了如何使用std :: exception类以标准方式实现自己的异常-
#include
#include
using namespace std;
struct MyException : public exception {
const char * what () const throw () {
return "C++ Exception";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
这将产生以下结果-
MyException caught
C++ Exception
在此, what()是异常类提供的公共方法,并且已被所有子异常类覆盖。这将返回异常原因。