C++中的异常处理机制详解

2020-01-06 17:21:42丽君


#include 
using namespace std;
int main() try {
 throw "main";
 } catch(const char* msg) {
 cout << msg << endl;
 return 1;
 }

 main函数语句块,可以捕获main函数中抛出的异常.


 class Base
 {
 public:
 Base(int data,string str)try:m_int(data),m_string(str)//对初始化列表中可能会出现的异常也会进行捕捉
 {
 // some initialize opt
 }catch(const char* msg) {
 cout << "catch a exception" << msg << endl;
 }
 private:
 int m_int;
 string m_string;
 };
int main()
 {
 Base base(1,"zhangyifei");
 }

上面说了很多都是关于异常的使用,如何定义自己的异常,编写异常是否应该遵循一定的标准,在哪里使用异常,异常是否安全等等一系列的问题,下面会一一讨论的.

标准异常

C++标准库给我们提供了一系列的标准异常,这些标准异常都是从exception类派生而来,主要分为两大派生类,一类是logic_error,另一类则是runtime_error这两个类在stdexcept头文件中,前者主要是描述程序中出现的逻辑错误,例如传递了无效的参数,后者指的是那些无法预料的事件所造成的错误,例如硬件故障或内存耗尽等,这两者都提供了一个参数类型为std::string的构造函数,这样就可以将异常信息保存起来,然后通过what成员函数得到异常信息.


#include 
#include 
#include 
using namespace std;
class MyError:public runtime_error {
 public:
 MyError(const string& msg = "") : runtime_error(msg) {}
};
//runtime_error logic_error 两个都是继承自标准异常,带有string构造函数
 //
 int main()
 {
 try {
 throw MyError("my message"); 
 } catch(MyError& x) {
 cout << x.what() << endl; 
 }
 }

异常规格说明

假设一个项目中使用了一些第三方的库,那么第三方库中的一些函数可能会抛出异常,但是我们不清楚,那么C++提供了一个语法,将一个函数可能会抛出的异常列出来,这样我们在编写代码的时候参考函数的异常说明即可,但是C++11中这中异常规格说明的方案已经被取消了,所以我不打算过多介绍,通过一个例子看看其基本用法即可,重点看看C++11中提供的异常说明方案:


#include 
#include 
#include 
#include 
using namespace std;
class Up{};
 class Fit{};
 void g();
 //异常规格说明,f函数只能抛出Up 和Fit类型的异常
 void f(int i)throw(Up,Fit) {
 switch(i) {
 case 1: throw Up();
 case 2: throw Fit(); 
 }
 g();
 }
void g() {throw 47;}
void my_ternminate() {
 cout << "I am a ternminate" << endl;
 exit(0);
 }
void my_unexpected() {
 cout << "unexpected exception thrown" << endl;
 // throw Up();
 throw 8;
 //如果在unexpected中继续抛出异常,抛出的是规格说明中的 则会被捕捉程序继续执行
 //如果抛出的异常不在异常规格说明中分两种情况
 //1.异常规格说明中有bad_exception ,那么会导致抛出一个bad_exception
 //2.异常规格说明中没有bad_exception 那么会导致程序调用ternminate函数
 // exit(0);
 }
int main() {
 set_terminate(my_ternminate);
 set_unexpected(my_unexpected);
 for(int i = 1;i <=3;i++)
 {
 //当抛出的异常,并不是异常规格说明中的异常时
 //会导致最终调用系统的unexpected函数,通过set_unexpected可以
 //用来设置自己的unexpected汗函数
 try {
 f(i); 
 }catch(Up) {
 cout << "Up caught" << endl; 
 }catch(Fit) {
 cout << "Fit caught" << endl; 
 }catch(bad_exception) {
 cout << "bad exception" << endl; 
 }
 }
 }
 }