如果抛出值匹配多个catch子句会发生什么

What happens if a thrown value matches several catch clauses?

本文关键字:子句 catch 什么 如果      更新时间:2023-10-16

如果一个抛出的值匹配多个catch子句会发生什么?

是编译器决定的还是出错的?

下面是一个抛出值并匹配三个catch子句的示例。

我编译它并得到错误。但是不知道这个错误是什么意思…

    #include <iostream>
    using namespace std;
    class AAA
    {
    public:
        void ShowYou() { cout<<"AAA exception!"<<endl; }
    };
    class BBB : public AAA
    {
    public:
        void ShowYou() { cout<<"BBB exception!"<<endl; }
    };
    class CCC : public BBB
    {
    public:
        void ShowYou() { cout<<"CCC exception!"<<endl; }
    };
    void ExceptionGenerator(int expn)
    {
        if(expn==1)
            throw AAA();
        else if(expn==2)
            throw BBB();
        else
            throw CCC();
    }
    int main(void)
    {
        try
        {
            ExceptionGenerator(1);
            ExceptionGenerator(1);
            ExceptionGenerator(1);
        }
        catch(AAA& expn)
        {
            cout<<"catch(AAA& expn)"<<endl;
            expn.ShowYou();
        }   
        catch(AAA& expn)
        {
            cout<<"catch(BBB& expn)"<<endl;
            expn.ShowYou();
        }
        catch(AAA& expn)
        {
              cout<<"catch(CCC& expn)"<<endl;
              expn.ShowYou();
        }
      system("pause"); return 0;
}

错误1 C2312: 'AAA &':被第40行'AAA &'捕获

我得到上面的错误。

这是什么意思?

出自n3337标准草案,15.3/4

try块的处理程序按照出现的顺序进行尝试。这使得编写处理程序成为可能永远不能执行,例如,将派生类的处理程序放在对应类的处理程序之后基类。

这意味着第二个和第三个catch块基本上是不可达的代码。尽管如此,你的程序是结构良好的,一个符合标准的编译器不应该拒绝它(例如,我的编译器只是发出警告)。

当你有一个异常层次结构时,使它们表现为多态以区分它们:

#include <iostream>
using namespace std;
class AAA {
public:
    virtual void ShowYou() { cout<<"AAA exception!"<<endl; }
};
class BBB : public AAA {
public:
    void ShowYou() { cout<<"BBB exception!"<<endl; }
};
class CCC : public BBB {
public:
    void ShowYou() { cout<<"CCC exception!"<<endl; }
};
void ExceptionGenerator()
{
    int expn = 0;
    cin >> expn;
    if(expn==1)
        throw AAA();
    else if(expn==2)
        throw BBB();
    else
        throw CCC();
}
int main(void)
{
    try
    {
        ExceptionGenerator();
    }
    catch(AAA& expn)
    {
        expn.ShowYou();
    }
    system("pause"); return 0;
}

我认为你的错误来自你的3捕获块,在你的代码中你捕获3次相同的异常类型。在try/catch块中,在catch块中跳转到第一个异常类型。因此,为了捕获类型AAAA、BBBB和CCCC的所有情况,必须按照派生优先级的顺序创建捕获块,如下所示:

catch(CCC& expn)
{
    cout<<"catch(CCC& expn)"<<endl;
    expn.ShowYou();
}   
catch(BBB& expn)
{
    cout<<"catch(BBB& expn)"<<endl;
    expn.ShowYou();
}
catch(AAA& expn)
{
      cout<<"catch(AAA& expn)"<<endl;
      expn.ShowYou();
}