throw 用作异常规范

2023-12-13 03:58:46

throw 用作异常规范

throw 关键字除了可以用在函数体中抛出异常,还可以用在函数头和函数体之间,指明当前函数能够抛出的异常类型,这称为异常规范(Exception specification),有些教程也称为异常指示符或异常列表。请看下面的例子:

double func (char param) throw (int);

这条语句声明了一个名为 func 的函数,它的返回值类型为 double,有一个 char 类型的参数,并且只能抛出 int 类型的异常。如果抛出其他类型的异常,try 将无法捕获,只能终止程序。

如果函数会抛出多种类型的异常,那么可以用逗号隔开:

double func (char param) throw (int, char, exception);

如果函数不会抛出任何异常,那么( )中什么也不写:

double func (char param) throw ();

如此,func() 函数就不能抛出任何类型的异常了,即使抛出了,try 也检测不到。

1) 虚函数中的异常规范

C++ 规定,派生类虚函数的异常规范必须与基类虚函数的异常规范一样严格,或者更严格。只有这样,当通过基类指针(或者引用)调用派生类虚函数时,才能保证不违背基类成员函数的异常规范。请看下面的例子:

class Base{
public:
    virtual int fun1(int) throw();
    virtual int fun2(int) throw(int);
    virtual string fun3() throw(int, string);
};
class Derived:public Base{
public:
    int fun1(int) throw(int);   //错!异常规范不如 throw() 严格
    int fun2(int) throw(int);   //对!有相同的异常规范
    string fun3() throw(string);  //对!异常规范比 throw(int,string) 更严格
}
2) 异常规范与函数定义和函数声明

C++ 规定,异常规范在函数声明和函数定义中必须同时指明,并且要严格保持一致,不能更加严格或者更加宽松。

请看下面的几组函数:

//错!定义中有异常规范,声明中没有
void func1();
void func1() throw(int) { }
//错!定义和声明中的异常规范不一致
void func2() throw(int);
void func2() throw(int, bool) { }
//对!定义和声明中的异常规范严格一致
void func3() throw(float, char*);
void func3() throw(float, char*) { }

请抛弃异常规范,不要再使用它

异常规范的初衷是好的,它希望让程序员看到函数的定义或声明后,立马就知道该函数会抛出什么类型的异常,这样程序员就可以使用 try-catch 来捕获了。如果没有异常规范,程序员必须阅读函数源码才能知道函数会抛出什么异常。

不过这有时候也不容易做到。例如,func_outer() 函数可能不会引发异常,但它调用了另外一个函数 func_inner(),这个函数可能会引发异常。再如,您编写的函数调用了老式的库函数,此时不会引发异常,但是库更新以后这个函数却引发了异常。总之,异常规范的初衷实现起来有点困难,所以大家达成的一致意见是,最好不要使用异常规范。

异常规范是 C++98 新增的一项功能,但是后来的 C++11 已经将它抛弃了,不再建议使用。

另外,各个编译器对异常规范的支持也不一样,请看下面的代码:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
void func()throw(char*, exception){
    throw 100;
    cout<<"[1]This statement will not be executed."<<endl;
}
int main(){
    try{
        func();
    }catch(int){
        cout<<"Exception type: int"<<endl;
    }
    return 0;
}

在?GCC?下,这段代码运行到第 7 行时程序会崩溃。虽然 func() 函数中发生了异常,但是由于 throw 限制了函数只能抛出 char*、exception 类型的异常,所以 try-catch 将捕获不到异常,只能交给系统处理,终止程序。

在 Visual C++ 下,输出结果为Exception type: int,这说明异常被成功捕获了。在 Visual C++ 中使用异常规范虽然没有语法错误,但是也没有任何效果,Visual C++ 会直接忽略异常规范的限制,函数可以抛出任何类型的异常。

?

文章来源:https://blog.csdn.net/liudong200618/article/details/134949641
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。