旅途

如果想飞得高,就该把地平线忘掉

异常规范

异常异常规范exception specification 提供
了一种方案它能够随着函数声明列出该函数可能抛出的异常它保证该函数不会抛出任何
其他类型的异常
异常规范跟随在函数参数表之后它用关键字throw 来指定后面是用括号括起来的异
常类型表例如我们可以如下修改iStack 类的成员函数的声明以增加适当的异常规范
class iStack {
public:
// ...
void pop( int &value ) throw(popOnEmpty);
void push( int value ) throw(pushOnFull);
private:
// ...
};

如果函数声明指定了一个异常规范,则同一函数的重复声明必须指定同一类型的异常规
范,同一函数的不同声明上的异常规范是不能累积的。例如
// 同一函数的两个声明
extern int foo( int = 0 ) throw(string);
// 错误: 异常规范被省略
extern int foo( int parm ) { }

如果函数抛出了一个没有被列在异常规范中的异常会怎么样程序只有在遇到某种不正
常情况时异常才会被抛出在编译时刻编译器不可能知道在执行时程序是否会遇到这些
异常因此一个函数的异常规范的违例只能在运行时刻才能被检测出来如果函数抛出了
一个没有被列在其异常规范中的异常则系统调用C++标准库中定义的函数unexpected()
unexpected()的缺省行为是调用terminate() 在某些条件下可能有必要改变unexpected()
执行的动作C++标准库提供了一种机制可让我们改变unexpected()的缺省行为

1 空的异常规范保证函数不会抛出任何异常例如函数no_problem()保证不会抛出任何
异常
extern void no_problem() throw();
2 如果一个函数声明没有指定异常规范则该函数可以抛出任何类型的异常
在被抛出的异常类型与异常规范中指定的类型之间不允许类型转换。例如
int convert( int parm ) throw(string)
{
// ...
if ( somethingRather )
// 程序错误:
// convert() 不允许 const char* 型的异常
throw "help!";
}
在函数convert()中的throw 表达式抛出一个C 风格的字符串由这个throw 表达式创建
的异常对象的类型为const char* 通常const char*型的表达式可以被转换成string 类型
但是异常规范不允许从被抛出的异常类型到异常规范指定的类型之问的转换如果convert()
抛出该异常则调用函数unexpected() 为了修正这种情况可以如下修改throw 表达式
显式地把表达式的值转换成string 类型
throw string( "help!" );
3
我们也可以在函数指针的声明处给出一个异常规范例如
void (*pf) (int) throw(string);
该声明表示pf 是一个函数指针它只能抛出string 类型的异常和函数声明一样同一
指针的不同异常规范不能累积指针pf 的所有声明都必须指定相同的规范例如
extern void (*pf)( int ) throw(string);
// 错误: 缺少异常规范
void (*pf) ( int );
void recoup( int, int ) throw(exceptionType);
void no_problem() throw();
void doit( int, int ) throw(string, exceptionType);
// ok: recoup() 与 pf1 的异常规范一样严格
void (*pf1)( int, int ) throw(exceptionType) = &recoup;
// ok: no_problem() 比 pf2 更严格
void (*pf2)() throw(string) = &no_problem;
// 错误: doit()没有 pf3 严格
void (*pf3)( int, int ) throw(string) = &doit;

posted on 2007-09-29 00:39 旅途 阅读(555) 评论(0)  编辑 收藏 引用 所属分类: C/C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理