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?
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; ^
live example on wandbox.org
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.
live example on wandbox.org
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With