Reputation: 1134
I created a custom exception class that derives from std::exception.
#include <iostream>
class Exception : std::exception {
public:
const char* what() const noexcept override {
return "test";
}
};
int main() {
try {
throw Exception();
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
}
This program, when compiled by g++ -stdc++=17
on Ubuntu, causes the exception to not get caught by the catch
block, even though catching by reference is supposed to catch derived exceptions too. It calls std::terminate
, even though it happens in a try
block that catches its base class by reference. Same thing happens if Exception
inherits from std::runtime_error
and passes "test"
to the std::runtime_error
constructor in its own constructor. Normally the solution would be to only catch using Exception
, but in my original code I need to catch different types of exceptions, all of which inherit from std::exception
. Why does this happen? Does catching by reference to base not work? How can I catch all exceptions deriving from std::exception
using one catch block?
Upvotes: 8
Views: 2136
Reputation: 93264
When you inherit from a base class during the definition of a class
, the default access modifier for the inheritance is private
. This means that the two following definitions are equivalent:
class derived : base { /* ... */ };
class derived : private base { /* ... */ };
The language doesn't allow1 you to refer to a derived class from a private base2. As an example, the following code does not compile:
int main()
{
derived d;
base& b = d; // <== compilation error
}
error: 'base' is an inaccessible base of 'derived' base& b = d; ^
This is the reason why your catch
block cannot handle Exception
. Change your inheritance to public
...
class Exception : public std::exception
...and your original code will work.
1 See [dcl.init.ref] and [conv.ptr].
2 Unless you're in the scope of derived
itself. See this live example on wandbox.org.
Upvotes: 10
Reputation: 117856
You need to publicly derive from std::exception
class Exception : public std::exception
Then your output is
test
For more details about this topic, please reference Difference between private, public, and protected inheritance.
Upvotes: 4