I Have a problem with inheritance in my own exception hierarchy.
The class Exception
has very good functionality (backtrace, logging, ...), so it is my base class for any exception. It inherits from std::exception
as I see suggested in many webpages. Also, I'm using a unit test framework that reports any std::exception
being throw unexpectedly. But in a final word, it is just for convenience.
Then, I have a new OutOfMemoryException
class which will be throw by a custom new_handler. This class inherits from Exception
, but also inherit from std::bad_alloc
for compatibility with existent code. This is more important I guess, since new
will not throw std::bad_alloc
anymore.
The problem here is obvious: since std::bad_alloc
derive from std::exception
, I have a dreaded diamond situation.
class Exception : public std::exception { };
class OutOfMemoryException : public Exception, public std::bad_alloc { };
Sadly, as you can see here stackoverflow.com... standard exceptions do not virtual inheritance, so std::exception
is an ambiguous base class.
Then:
Is it possible to solve this in any way? (I don't know, any class or template trick)
If it is not, is preferable that Exception
does not inherit from std::exception
or OutOfMemoryException
does not from std::bad_alloc
I could hack the unit test framework due its permissive licence.
Thank you in advance and sorry, I am not a very good english speaker.
There is a way to have your extra exception functionality but without having to create another exception hierarchy. I.e. you can throw standard exceptions with your extra bits:
struct MyExceptionInfo { /* your extra functionality goes here */};
template<class T>
struct Ex : T, MyExceptionInfo
{
template<class A1, class... Args>
Ex(A1&& a1, Args&&... args)
: T(std::forward<A1>(a1))
, MyExceptionInfo(std::forward<Args>(args)...)
{}
};
int main() {
try {
throw Ex<std::runtime_error>("oops");
}
catch(std::exception &e) {
if(MyExceptionInfo* my_info = dynamic_cast<MyExceptionInfo*>(&e)) {
// use MyExceptionInfo here
}
}
}
You may also like taking a look at Boost.Exception library for inspiration.
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