Implementing an Exception Class in C ++

So, I'm trying to write a simple Exception base class for C ++, based on the Java Exception class. I am sure that there are already excellent libraries there, but I do it for practice, and not for production code, and I am curious and always want to learn. One of the things that Java Exception does that I would like to implement is the concept of "cause." In Java, a new exception with a reason is as follows:

Exception cause = new Exception(); Exception newExcept = new Exception(cause); 

However, in C ++, passing exceptions as an argument to the constructor is a call to the copy constructor. So, there is a conceptual disconnect between copying an Exception and creating a new Exception with a reason. Obviously, this is not a problem in Java.

I think I'm just wondering what is the best way to handle this. I had several ideas:

  • Differentiate using a dummy variable
  • Just create a new exception and call the setCause () method
  • Something like an Exception(Exception &) copy constructor Exception(Exception &) , and a constructor with a reason is Exception(Exception *)

thanks

+4
source share
4 answers

The exception - if allocated on the stack (I would highly recommend this) - is thrown after the catch clause. Therefore, you need to create a copy of the "internal" exception in the newly created exception. If you catch the base class of your exception, it will lose its correct type unless you provide an exception to the cloning method.

 #include <string> #include <exception> class MyBaseException : public std::exception { public: MyBaseException(const std::string& what = std::string("MyBaseException")) : m_BaseException(0), m_What(what) {} //Constructor without inner exception MyBaseException(const MyBaseException& innerException, const std::string& what = std::string("MyBaseException")) : m_BaseException(innerException.clone()), m_What(what) {} //Constructor with inner exception template <class T> // valid for all subclasses of std::exception MyBaseException(const T& innerException, const std::string& what = std::string("MyBaseException")) : m_BaseException(new T(innerException)), m_What(what) {} virtual ~MyBaseException() throw() { if(m_BaseException) { delete m_BaseException; } } //don't forget to free the copy of the inner exception const std::exception* base_exception() { return m_BaseException; } virtual const char* what() const throw() { return m_What.c_str(); } //add formated output for your inner exception here private: const std::exception* m_BaseException; const std::string m_What; virtual const std::exception* clone() const { return new MyBaseException(); } // do what ever is necesary to copy yourselve }; int main(int argc, char *argv[]) { try { try { throw std::exception(); } catch(const std::exception& e) { throw MyBaseException(e, "bad"); } } catch (const MyBaseException& e) { throw MyBaseException(e, "even worse"); } //throw MyBaseException(1, "will not compile"); } 
+5
source

You can use the factory model:

 Exception cause = Exception.Create(); Exception newExcept = Exception.Create( Exception cause ); 
+2
source

Just add the reason exception line to the current exception:

 try { throw std::runtime_error("Failed to work"); } catch(std::exception const& e) { // New exception (add origianl exception text). throw std::runtime_error(std::string("We were doing poobar when: ") + e.what()); } 
+1
source

You doubt it, and it doesn't even look like Java, but the Java idiom, which is supported by the library. I assume that the idiom you are describing passes the original exception as an argument to the exception that you create when you re-create.

The solution is to create an exception library (or whatever you want to call)

 class library_exception: public std::exception { ... public: library_exception(const std::exception &e) ... } ... catch(const std::exception &e) { ... throw library_exception(e); } 

Various classes that the copy constructor did not call.

0
source