设为首页 加入收藏

TOP

c++中的异常 exception
2015-11-21 00:59:31 来源: 作者: 【 】 浏览:1
Tags:异常 exception

变成入门的时候可能经常遇到的错误:

?

this application has requested the runtime to terminate it in an unusual way. Please contact the application's support team for more information
这是由于程序在运行时发生了未知的错误,例如:打开不存在的文件,爆栈,除数为0等错误,程序直接调用abort()函数直接终止程序的运行;当然,显示的信息不一定就是上面这一条

?

?

上面这个情况是程序自己解决异常的问题,这种方式实际上是非常粗暴的,直接终止了程序运行,而且你还不知道程序错在哪个位置,是因为什么错(当然,用万能的cout强行追踪也是阔以滴,哈哈)

所幸,c++引入了比较优雅的try... catch....异常机制来让程序猿自己处理可能出现的异常,这种机制实际上是避免了程序直接调用abort()函数,使程序看起来更优雅一点,具体结构如下:

?

try{
// 可能会引发异常的代码块
}catch(exception argument){
//处理捕捉到的异常
}
try...catch...机制实际上主要是以下几个部分:

?

1.将可能引发异常的代码(如:文件读取等)放入try块中

2.判断在什么时候抛出异常,也就是可能引发异常的代码块中需要添加异常抛出的语句,抛出异常通常使用 throw关键字

3.catch首先通过异常参数列表匹配产生的异常,如果匹配成功,那么执行catch块的代码

先写一个简单的例子

首先是没有异常处理的

?

#include 
  
   
using namespace std;

int division(int a, int b){
	return a / b;
}

int main(){
	int a, b;
	while(1){
		cout << Please input a and b: ;
		cin >> a >> b;
		cout << a / b =  << division(a, b) << endl;
	}
	return 0;
}
  
随便测试了一下,结果如下:

?

\

可以看到程序是直接结束了,并没有理会那个while(1)

那我们现在来加一下异常

?

#include 
  
   
using namespace std;


int division(int a, int b){

    if(b == 0)

    throw Divisor is not allowed to be 0;

    return a / b;
}


int main(){

    int a, b;

    while(1){

    cout << Please input a and b: ;

    cin >> a >> b;

    try{

    cout << a / b =  << division(a, b) << endl;

    cout << successful division << endl;

    }catch(const char* msg){

    cout << Error message is:  << msg << endl;?

    }

    

    }

    return 0;
}

  
运行结果:

?

\

可以看到现在我们可以知道是哪个地方除了问题,并且可以print出异常信息,更重要的是,程序依然可以继续往下执行

可以看到,在产生异常之后,程序马上跳转到匹配的catch块执行,而终止try块中代码的执行

当然,如果没有匹配上产生的异常(上面这个例子只是简单的匹配字符串,实际上更常用的是异常对象匹配),那么程序同样会调用abort()函数,然后编译器给你提示一堆错误的信息时候,你的程序就挂掉了

看了上面这个例子,是不是感觉try和catch有一点实参和型参的感觉

那下面我们来看一个例子

我们现在吧异常当作一个MyException的对象来处理:

?

#include 
  
   
using namespace std;

class MyException{
public:
	MyException(){
		msg = ;
		cout << in the default constructor << endl;
	}
	MyException(MyException &aa){
		msg = aa.msg;
		cout << in the copy constructor << endl;
	}
	MyException(string msg_){
		msg = msg_;
		cout << in the string constructor << endl;
	}
	string what(){
		return msg;
	}
	string msg;
};

int division(int a, int b){
	if(b == 0){
		MyException me(Divisor is not allowed to be 0);
		throw me;
	}
		
	return a / b;
}

int main(){
	int a, b;
	while(1){
		cout << Please input a and b: ;
		cin >> a >> b;
		try{
			cout << a / b =  << division(a, b) << endl;
			cout << successful division << endl;
		}catch(MyException &ME){
			cout << Error message is:  << ME.what() << endl; 
		}
		
	}
	return 0;
}
  
运行结果如下:

?

\

这里大家可能会疑惑,因为在正常的函数参数传递中,我们传递引用就是为了避免重复地构造对象,但是在try...catch...中就不一样了,throw在抛出异常的时候,无论catch是接受引用传递还是接受值传递,编译器都会在throw异常时新建一个临时对象,所以才会有上面结果中显示的两次构造MyException对象,而catch中的引用不过是指向这个临时对象而不是原本的那个MyException对象,一搬都是吧抛出异常跟新建异常对象合并在一起,这样更简洁,所以上面抛出异常可以写成

?

throw MyException(Divisor is not allowed to be 0);
本来还想说一下exception和他的一些派生类的,不过好像网上挺多这些东西的,也没什么可讲的,就收工了吧

?

?


?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU3605Escape(最大流SAP+状态压.. 下一篇hdu Bone Collector(背包)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: