c++ exception

c++ exception

常的描述 
函数和函数可能抛出的异常集合作为函数声明的一部分是有价值的,例如 

void f(int a) throw (x2,x3);表示f()只能抛出两个异常x2,x3,以及这些类型派生的异常,但不会抛出其他异常。如果f函数违反了这个规定,抛出了x2,x3之外的异常,例如x4,那么当函数f抛出x4异常时, 
会转换为一个std::unexpected()调用,默认是调用std::terminate(),通常是调用abort()。 

如果函数不带异常描述,那么假定他可能抛出任何异常。例如: 

int f(); //可能抛出任何异常不带任何异常的函数可以用空表表示: 

int g() throw (); // 不会抛出任何异常捕获异常 
捕获异常的代码一般如下: 


try { throw E();}catch (H h) { //何时我们可以能到这里呢} 
1.如果H和E是相同的类型 

2.如果H是E的基类 

3.如果H和E都是指针类型,而且1或者2对它们所引用的类型成立 

4.如果H和E都是引用类型,而且1或者2对H所引用的类型成立 

从原则上来说,异常在抛出时被复制,我们最后捕获的异常只是原始异常的一个副本,所以我们不应该抛出一个不允许抛出一个不允许复制的异常。 

此外,我们可以在用于捕获异常的类型加上const,就像我们可以给函数加上const一样,限制我们,不能去修改捕捉到的那个异常。 

还有,捕获异常时如果H和E不是引用类型或者指针类型,而且H是E的基类,那么h对象其实就是H h = E(),最后捕获的异常对象h会丢失E的附加携带信息。 



异常处理的顺序 
我们之前写的parseNumber函数会抛出NumberParseException,这个函数只是判断是否数字才抛出异常,但是没有考虑,但这个字符串表示的整数太大,溢出,抛出异常Overflow.表示如下: 

class NumberParseException {};class Overflow : public NumberParseException {};假设我们parseNumber函数已经为字符串的整数溢出做了检测,遇到这种情况,会抛出Overflow异常,那么异常捕获代码如下: 


char *str1 = "1", *str2 = NULL; try { int num1 = parseNumber(str1); int num2 = parseNumber(str2); printf("sum is %d\n", num1 + num2); } catch (Overflow) { //处理Overflow或者任何由Overflow派生的异 常 } catch (NumberParseException) { //处理不是Overflow的NumberParseException异常 } 
异常组织这种层次结构对于代码的健壮性很重要,因为库函数发布之后,不可能不加入新 的异常,就像我们的parseNumber,第一次发布时只是考虑输入是否一个整数的错误,第二次发布时就考虑了判断输入的一个字符串作为整数是否太大溢 出,对于一个函数发布之后不再添加新的异常,几乎所有的库函数都不能接受。 

如果没有异常的层次结构,当函数升级加入新的异常描述时,我们可能都要修改代码,为每一处调用这个函数的地方加入对应的catch新的异常语句,这很让你厌烦,程序员也很容易忘记把某个异常加入列表,导致这个异常没有捕获,异常退出。 

而有了异常的层次结构,函数升级之后,例如我们的parseNumber加入了Overflow异常描述,函数调用者只需要在自己感兴趣的调用场景加入catch(Overflow),并做处理就行了,如果根据不关心Overflow错误,甚至不用修改代码。


/*
* exception.h
*
* Created on: 2013-7-18
* Author: bigmac
*/

#ifndef EXCEPTION_H_
#define EXCEPTION_H_
#include<exception>
#include<iostream>
using namespace std;

class myexception : public exception
{
public:
myexception() throw() { }
myexception(const string &err) throw (exception){
this->error=err;
}

~myexception() throw();

const char* what() const throw(){
return error.data();
}
private :
string error;

};


#endif /* EXCEPTION_H_ */

//============================================================================
// Name : exception.cpp
// Author : 
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include"exception.h"
using namespace std;

int main() {
try{
throw string("nihao");
// throw exception();
// cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!\t
// return 0;
}
catch (string & e){
cout<<e<<endl;
cout<<"string e";
}
catch (exception &e){
cout<<e.what();
cout<<"exception ";
}
}



参考文献:

http://kb.cnblogs.com/kb/79171/

 

你可能感兴趣的:(C++)