Reputation: 99
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"?
I was pretty sure WyjatekNieoznaczony() should be thrown because a=0 and b=0 as well. 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;
}
Upvotes: 0
Views: 168
Reputation: 13424
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'.
This basically means that WyjatekNieoznaczony
, by inheriting from Wyjatek
, will be first caught by catch(Wyjatek)
clause, since it's convertible. The problem is that due to object slicing, it will lose its Nieoznaczony
ness.
What I suggest is to reorder the catch
clauses so the possibility of slicing disappears (in this case):
catch (WyjatekBledny) {
cout << "Wyjatek bledny" << endl;
throw 1;
}
catch (WyjatekNieoznaczony) {
cout << "Wyjatek nieoznaczony" << endl;
throw;
}
catch (Wyjatek) {
cout << "Wyjatek" << endl;
}
Upvotes: 3
Reputation: 234665
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.
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.
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.
Upvotes: 4