MoreeffectiveC++:审慎使用异常规格

MoreeffectiveC++:审慎使用异常规格,第1张

MoreeffectiveC++:审慎使用异常规格,第2张

毫无疑问,异常规范是一个吸引人的特性。这使得代码更容易理解,因为它清楚地描述了函数可以抛出什么样的异常。但这不仅仅是一个有趣的笔记。编译器有时可以在编译时检测到异常规范的不一致性。而且,如果一个函数抛出一个不在异常规范内的异常,系统可以在运行时检测到这个错误,然后会自动调用一个意外的特殊函数。规范既可以作为指导性文件,也可以作为非正常使用的强制性约束机制,看起来还很有吸引力。

但是,一般情况下,美丽只是表面的,外在的美丽并不代表内在的品质。意外函数的默认行为是调用终止函数,而终止函数的默认行为是调用中止函数,所以违反异常规范的程序的默认行为是halt。被激活的堆栈框架中的局部变量不会被释放,因为abort在关闭程序时不会执行这样的清除操作。非正常规范的违反,已经成为一场不该发生的灾难。

不幸的是,很容易编写导致这种灾难的函数。编译器只是部分地检测异常的使用是否符合异常规范。一个函数调用另一个函数,后者可能抛出违反前者异常规范的异常。(A函数调用B函数,这违反了A函数的异常规范,因为B函数可能抛出不在A函数异常规范内的异常。)编译器不会检测到这种情况,语言标准也禁止它们拒绝这个调用(虽然可以显示警告信息)。

例如,如果函数f1没有声明异常规范,这样的函数可以抛出任何类型的异常:

外部void f1();//可以抛出任何异常。

假设有一个函数f2通过它的异常规范声明它只能抛出int类型的异常:

void F2()throw(int);

f2调用f1是非常合法的,即使f1可能抛出违反F2异常规范的异常:

void F2()throw(int)
{
...
f1();//即使f1可能会抛出不属于int类型的
//异常,但这是合法的。
...
}

当具有异常规范的新代码与没有异常规范的旧代码集成时,这种灵活性非常重要。

因为你的编译器允许你调用一个函数,它抛出的异常与调用函数的异常规范不一致,这样的调用可能会导致你的程序执行被终止,所以写软件的时候要采取措施尽量减少这种不一致。一个好方法是避免在带有类型参数的模板中使用异常规范。例如,下面的模板似乎不能抛出任何异常:

//一个设计很差的模板wrt异常规范
template
bool operator = =(const T & lhs,const T & RHS)throw()
{
return & lhs = = & RHS;
}

该模板为所有类型定义了一个运算符函数operator==。对于任何一对相同类型的对象,如果对象具有相同的地址,该函数返回true,否则返回false。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » MoreeffectiveC++:审慎使用异常规格

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情