Reputation: 627
Consider the following code snippet
try {
goesWrong();
}
catch (const std::bad_alloc &e)
{
std::cout << "Catching bad_alloc: " << e.what() << std::endl;
}
catch (const std::exception &e)
{
std::cout << "Catching exception: " << e.what() << std::endl;
}
Why do we need to catch a lot of individual exceptions. Just std::exception
at the end is enough to catch all exceptions isn't it ? Why an extra 4 lines of code to catch std::bad_alloc
explicitly when std::exception
is going to catch it anyway?
Upvotes: 0
Views: 168
Reputation: 36479
The separate catch statements are so that you have have different behaviour depending on the type of exception thrown.
For example you might be expecting a bad_alloc
and can recover from it by trying again with a smaller allocation or by freeing memory elsewhere.
Just std::exception at the end is enough to catch all exceptions isn't it ?
No, catching std::exception
is enough to catch all thrown exceptions which are derived from std::exception
. In c++ std::exception
doesn't have any special meaning, you can throw any type as an exception. It is recommended to derive from std::exception
but not required.
There are even pitfalls like if you have multiple inheritance and your exception class derives from std::exception
twice it won't be caught.
To catch all exceptions you need to catch ...
:
struct my_exception {};
try
{
switch ( i )
{
case 1:
throw std::runtime_error( "i is 1" );
case 2:
// bad idea, who is responsible for freeing the exception? But perfectly legal
throw new std::runtime_error( "i is 1" );
case 3:
// you can throw numbers too
throw i;
case 4:
throw my_exception();
}
}
catch ( const std::exception& )
{
}
catch ( const my_exception& )
{
}
catch ( ... )
{
}
Upvotes: 2
Reputation: 25536
More an addition to the answers given so far than a separate, own one:
Actually, you could base exception handling on evaluation of the what()
string:
catch(std::exception const& e)
{
if(strcmp(e.what(), "some text"))
{
doThis();
}
else if(strstr(e.what(), "something"))
{
doThat();
}
// ...
}
However, this requires that you know the exact string contents. What, if these differ across different C++ implementations? What, if these are localised on some systems? Do you really want to cope with all such matters? Additionally, text processing is much more expensive than just catching different exceptions.
So with different exceptions, you gain portability, safety (consider typos in the strings you compare with...), easier and better readable code and, as a bonus, efficiency.
Upvotes: 1
Reputation: 238401
Why do we need to catch a lot of individual exceptions.
In general, because that allows different behaviour depending on the type of the caught exception.
In this case, there's need to do so, since this possibility is not taken advantage of.
Consider for example a case where you have allocated a large cache in memory. In that case, when catching std::bad_alloc
, you might release the cache and try again, while that approach would not be useful in the case of other exceptions.
Upvotes: 3
Reputation: 122830
exception
could be any expception while bad_alloc
is more specific. Not only you might want to react differently for different kind of exceptions, but also it more clearly expresses what is going on. After all code is written to express your intention not just to make it work somehow.
Upvotes: 2