How to throw an exception by type of runtime?

I want to call a function that can throw an exception. If it throws an exception, I want to catch it and pass the exception object to the handler function. By default, the implementation of a handler function is just an exception. Below is the code with reduced code to illustrate the problem:

struct base_exception : exception { char const* what() const throw() { return "base_exception"; } }; struct derived_exception : base_exception { char const* what() const throw() { return "derived_exception"; } }; void exception_handler( base_exception const &e ) { throw e; // always throws a base_exception object even if e is a derived_exception } int main() { try { throw derived_exception(); } catch ( base_exception const &e ) { try { cout << e.what() << endl; // prints "derived_exception" as expected exception_handler( e ); } catch ( base_exception const &e ) { cout << e.what() << endl; // prints "base_exception" due to object slicing } } } 

However, throw e in exception_handler() returns a copy of the static type of the exception, i.e. base_exception . How can I make exception_handler() throw an actual exception that has the correct type of runtime derived_exception ? Or how can I redo things to get what I want?

+4
source share
4 answers

You can put the throw_me virtual function in the base exception class and override each derived class. Derived classes can invoke the corresponding most derived type, without slicing. Despite the fact that the function has the same definition in each class, they do not match - the *this type is different in each case.

 struct base_exception : exception { char const* what() const throw() { return "base_exception"; } virtual void throw_me() const { throw *this; } }; struct derived_exception : base_exception { char const* what() const throw() { return "derived_exception"; } virtual void throw_me() const { throw *this; } }; void exception_handler( base_exception const &e ) { e.throw_me(); } 
+3
source

You can use throw; to re-throw the excluded object. You can also use a template.

template<typename T> void rethrow(const T& t) { throw t; }

+2
source

Throw in value, grab the link . This will save you a lot of headaches.

0
source

What you are looking for is called "propagating" the exception. To do this, you need to use the throw keyword with no parameters inside the catch . It will not copy the exception, and the exception will be caught by the next catch in its path or will make your program abort if it is not detected again.

-1
source

Source: https://habr.com/ru/post/1345099/


All Articles