简体   繁体   English

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

[英]Why is this exact exception thrown in my c++ code?

I am analyzing part of code that was part of my lectures.我正在分析我讲座中的部分代码。 I have managed to compile it but I cannot understand: why does my program output "Wyjatek" and 0 instead of "WyjatekNieoznaczony"?我已经设法编译它,但我无法理解:为什么我的程序输出“Wyjatek”和 0 而不是“WyjatekNieoznaczony”?

I was pretty sure WyjatekNieoznaczony() should be thrown because a=0 and b=0 as well.我很确定 WyjatekNieoznaczony() 应该被抛出,因为 a=0 和 b=0 也是如此。 Right now i am a little bit confused.现在我有点困惑。 Could you help me, please?请问你能帮帮我吗?

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;
}

Yes indeed a WyjatekNieoznaczony is thrown, but at the catch site, catch (Wyjatek) { is a match (due to the inheritance) so it's caught there.是的,确实抛出了WyjatekNieoznaczony ,但在捕获站点, catch (Wyjatek) {是匹配项(由于继承),因此它在那里被捕获。

A catch site is more like an if else block in behaviour - with each catch possibility being considered in the order they are written - rather than a switch block where you can put the labels in any order you like.捕获站点更像是行为中的if else块 - 每个catch可能性都按照它们的编写顺序进行考虑 - 而不是一个switch块,您可以在其中按您喜欢的任何顺序放置标签。

Note also that it's a good idea to catch exceptions by const reference than by value, else you can suffer the pitfalls of object slicing .另请注意,通过const引用而非值来捕获异常是个好主意,否则您可能会遇到对象切片的陷阱。

If you enabled (and read) compiler warnings, you would've encountered the following diagnostic:如果您启用(并阅读)编译器警告,您会遇到以下诊断信息:

warning: exception of type 'WyjatekNieoznaczony' will be caught [...] by earlier handler for 'Wyjatek'.警告:“WyjatekNieoznaczony”类型的异常将被“Wyjatek”的早期处理程序捕获[...]。

This basically means that WyjatekNieoznaczony , by inheriting from Wyjatek , will be first caught by catch(Wyjatek) clause, since it's convertible.这基本上意味着WyjatekNieoznaczony ,通过从Wyjatek继承,将首先被catch(Wyjatek)子句catch(Wyjatek) ,因为它是可转换的。 The problem is that due to object slicing , it will lose its Nieoznaczony ness.问题在于,由于对象切片,它将失去其Nieoznaczony性。

What I suggest is to reorder the catch clauses so the possibility of slicing disappears (in this case):我的建议是重新排序catch子句,这样切片的可能性就消失了(在这种情况下):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM