1

从字面上看,如果抛出的一个值与多个 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 &' 捕获

我得到上面的错误。

这是什么意思?

4

2 回答 2

1

来自 n3337 标准草案,15.3/4

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;
}
于 2013-04-27T08:11:34.833 回答
0

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

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();
}
于 2013-04-27T08:20:59.277 回答