Following code is about exception handling. I got the output:
Botch::f()
I'll be back!
Why Fruit is not caught? Thanks!
Ignore this. I think I have provided enough detail.
#include <exception>
#include <iostream>
using namespace std;
void terminator() {
cout << "I'll be back!" << endl;
exit(0);
}
void (*old_terminate)() = set_terminate(terminator);
class Fruit {};
class Botch {
public:
void f() throw(Fruit, bad_exception) {
cout << "Botch::f()" << endl;
throw Fruit();
}
~Botch() { throw 'c'; }
};
int main() {
try{
Botch b;
b.f();
} catch(Fruit&) {
cout << "inside catch(Fruit)" << endl;
} catch(bad_exception&) {
cout << "caught a bad_excpetionfrom f" << endl;
}
}
Because during stack unwinding for your Fruit exception you threw another exception (from the Botch
destructor). So your terminator was called instead. This is why throwing exceptions from a destructor is a bad idea,
Fruit
is not caught because the code never reaches that catch clause. In the try
block in main
, the call to bf()
throws an exception of type Fruit
. In response, the code destroys the Botch
object before entering the catch clause. The destructor of Botch
throws another exception, and that triggers the call to terminate
.
When bf()
is called in main, a Fruit
is thrown. Then execution leaves the try
block, and before any catch handler can catch that Fruit
, b
is destroyed and 'c'
is thrown. Throwing a second exception while the Fruit
is still active leads to termination, regardless of any catch handlers.
This is the reason why you never shall throw from destructors.
because the program flow is as follows:
try{
Botch b;
b.f();
//-> exception of class Fruit has been thrown
//-> Stack unwinding: during stack unwinding object b,
//which is on stack is destroyed, and its destructor is called
//-> this destructor ~Botch() { throw 'c'; } throws another exception
//and this caused call of your terminator()
} catch(Fruit&) { // so we are never here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.