为什么在我的C ++代码中抛出此确切异常?

时间:2019-07-01 12:07:59

标签: c++ exception try-catch

我正在分析属于我的讲座的一部分代码。 我设法编译了它,但我不明白: 为什么我的程序输出“ Wyjatek”和0而不是“ WyjatekNieoznaczony”?

我非常确定应该抛出WyjatekNieoznaczony(),因为a = 0和b = 0也是如此。现在我有点困惑。 你能帮我吗?

class Wyjatek {};
class WyjatekBledny : public Wyjatek {};
class WyjatekNieoznaczony : public Wyjatek {};

double f(double a, double b) {
    if (b == 0) {
        if (a == 0)
            throw WyjatekNieoznaczony();
        else
            throw WyjatekBledny();
    }
    return a / b;
}


double g(double a, double b) throw (int) {
    try {
        return f(a, b);
    }
    catch (WyjatekBledny) {
        cout << "Wyjatek bledny" << endl;
        throw 1;
    }
    catch (Wyjatek) {
        cout << "Wyjatek" << endl;
    }
    catch (WyjatekNieoznaczony) {
        cout << "Wyjatek nieoznaczony" << endl;
        throw;
    }
    return 0;
}

int main()
{
    double a = 0, b = 0;
    try {
        cout << g(a, b) << endl;
    }
    catch (...)
    {
        cout << "Inny wyjatek" << endl;
    }
    system("pause");
    return 0;
}

2 个答案:

答案 0 :(得分:5)

是的,确实抛出了WyjatekNieoznaczony,但是在捕获站点,catch (Wyjatek) {是一个匹配项(由于继承),因此被捕获了。

捕获站点的行为更像是if else块-每个catch的可能性都按照其写入顺序来考虑-而不是switch块您可以在其中按自己喜欢的顺序放置标签。

还请注意,通过const引用捕获异常而不是通过值捕获异常是一个好主意,否则您可能会遇到对象切片的陷阱。

答案 1 :(得分:3)

如果启用(并读取)编译器警告,则会遇到以下诊断:

  

警告:“ WyjatekNieoznaczony”类型的异常将由“ Wyjatek”的早期处理程序捕获。

这基本上意味着WyjatekNieoznaczony(从Wyjatek继承)将首先被catch(Wyjatek)子句捕获,因为它是可转换的。问题是由于object slicing,它将失去其Nieoznaczony的性质。

我建议对catch子句重新排序,以使切片的可能性消失(在这种情况下):

catch (WyjatekBledny) {
    cout << "Wyjatek bledny" << endl;
    throw 1;
}
catch (WyjatekNieoznaczony) {
    cout << "Wyjatek nieoznaczony" << endl;
    throw;
}
catch (Wyjatek) {
    cout << "Wyjatek" << endl;
}