程序的错误大致可以分为三种,分别是语法错误、逻辑错误和运行时错误:运行时错误是指程序在运行期间发生的错误,例如除数为 0、内存分配失败、数组越界、文件不存在等。C++ 异常(Exception)机制就是为解决运行时错误而引入的。
C++异常处理机制
C++语言的异常处理机制通过3个关键字
throw、try和catch实现。
try
:检测可能的会出现的语句范围;
throw:抛出异常;
catch:捕获抛出的异常;
try{
// 可能抛出异常的语句
}
catch(exceptionType variable 1){
// 处理异常的语句
}
catch(exceptionType variable 2){
// 处理异常的语句
}
捕获所有的标准异常:
try{
//可能抛出异常的语句
}
// 之所以使用引用,是为了提高效率。如果不使用引用,就要经历一次对象拷贝(要调用拷贝构造函数)的过程
catch(exception &e){
//处理异常的语句
}
任何需要检测(或是可能出现异常)的语句必须在try语句块中执行,并由throw语句抛出异常。throw语句抛出异常后,catch利用数据类型匹配进行异常捕获。
【注】:
1、try后可以有更多的catch语句;
2、异常抛出后程序根据异常类型匹配相应的类型;
3、若无异常,则跳转到try后面的catch继续执行;
实例
#include<bits/stdc++.h>
using namespace std;
double divide(double a, double b){
if(b == 0){
throw b;
return 0.0;
}
return a / b;
}
int main(){
double a = 3.0, b = 0;
try{
divide(a, b);
}
catch(double b){
cout << "denominator = " << b << " is error\n" << endl;
}
return 0;
}
C++ 标准异常
标准异常都在头文件<exception>中,
std::exception,该异常为所有C++标准异常的的父类;
std::bad_alloc,该异常可以通过new抛出;
std::bad_cast,该异常可以通过dynamic_cast抛出;
std::bad_typeid:改异常可以通过typeid抛出;
std::bad_exception:在C++程序无法预期的异常时非常有用;
其他就不细说....
class
exception{
public:
exception () throw(); //构造函数
exception (const exception&) throw(); //拷贝构造函数
exception& operator= (const exception&) throw(); //运算符重载
virtual ~exception() throw(); //虚析构函数
virtual const char* what() const throw(); //虚函数
}
what() 函数返回一个能识别异常的字符串,正如它的名字“what”一样,可以粗略地告诉你这是什么异常。
不过C++标准并没有规定这个字符串的格式,各个编译器的实现也不同,所以 what() 的返回值仅供参考。
【注】:
关键字throw
throw(something)是对这个函数的异常安全作出限制;这是一种异常规范,只会出现在声明函数时,表示这个函数可能抛出任何类型的异常
void fun() throw(exceptionType); //
表示fun函数只能抛出exceptionType类型的异常。
举例来说:
void func_1() throw(int); // 并不表示一定会抛出异常,但是一旦抛出异常只会抛出int类型
void func_2() throw(int,char); // 表示抛出int,char类型异常
void func_3() throw(); // 表示不会抛出任何类型异常
void func()_4 throw(...); // 表示抛出任何类型异常