There is the following code, from here
class Base {
int i;
public:
class BaseExcept {};
Base(int i) : i(i) { throw BaseExcept(); }
};
class Derived : public Base {
public:
class DerivedExcept {
const char* msg;
public:
DerivedExcept(const char* msg) : msg(msg) {}
const char* what() const { return msg; }
};
Derived(int j) try : Base(j) {
// Constructor body
cout << "This won't print" << endl;
}
catch (BaseExcept&) {
throw DerivedExcept("Base subobject threw");;
}
};
int main() {
try {
Derived d(3);
}
catch (Derived::DerivedExcept& d) {
cout << d.what() << endl; // "Base subobject threw"
}
}
My question is, why the thrown exception is not caught here
catch (BaseExcept&) {
throw DerivedExcept("Base subobject threw");;
}
But the catch in main?
catch (Derived::DerivedExcept& d) {
cout << d.what() << endl; // "Base subobject threw"
}
Why does it output "Base subobject threw"
According to my understanding, the thrown exception should be caught in the catch after try (or the function body equivalent to try), but there is no, why? What is the propagation path of the exception?
code from there
My question is this, try catch
I have seen before all have this form.
try{}
catch(){}
So I think for the following snippet
Derived(int j) try: Base(j) {
// Constructor body
cout << "This won't print" << endl;
}
catch (BaseExcept&) {
throw DerivedExcept("Base subobject threw");;
}
When Derived()
throws an exception, it should be caught by the catch (BaseExcept&)
in the following line, not by the catch (Derived::DerivedExcept& d)
in the main function.
But when I comment out it here
catch (Derived::DerivedExcept& d) {
//cout << d.what() << endl; // "Base subobject threw"
}
There will be no "Base subobject threw" output. This is different from what I expected. I am learning basic exception knowledge. Did I understand something wrong
CodePudding user response:
Derived(int j) try : Base(j) {
// Constructor body
cout << "This won't print" << endl;
}
catch (BaseExcept&) { // why the thrown exception is not caught here
throw DerivedExcept("Base subobject threw");;
}
The only way for the program to output Base subobject threw
is if the exception is actually caught where you do not think it's caught. The string does not exist anywhere else in the program.
But the catch in main?
That's because you throw
an exception in the catch
. That exception is not caught by the same catch
(which would result in infinite recursion in this case). It's caught by the outer try..catch
which you have in main
.