All My Brain Where stuff from my brain lands

May 12, 2009

Extending std::exception

Filed under: Programming — Tags: , , , — Dennis @ 4:06 pm

So you’re writing some C++ code, feeling all object oriented and all, and you decide you’d like an application specific exception whenever one of your methods has an issue. You’d like to have error messages that the exception can print up if thrown and you think to yourself, “hey, I’ll just extend std::exception, add the error string, and be on my way.”

Problem: So here is the puzzle. What is wrong with this code:

#include 
#include 
using namespace std;
class my_error : public exception {
  private:
   string m_err;
  public:
    my_error ( const string &err) : m_err(err) {}
    const char* what() { return m_err.c_str(); }
};

Think about it for a bit before scrolling down more. Take a look at the header definition for exception.

Ok, ready to move on? Did you find the problem?

Answer:

The standard exception does not declare it’s copy constructor virtual.

 exception& operator= (const exception&) throw();

This is in part because in order to provide exception safe c++, the exception class can’t throw exceptions itself. This is the same reason using strings member variables is discouraged for exceptions. Their constructors can also throw exceptions. Anyway, the result is that if client code catches std::exception, copies the exception, and prints it, m_str hasn’t been copied and you get garbage or errors. Not what was expected was it.

Solution

This whole problem was loaded just slightly. There is already a standard exception that can take a string message as an argument.

#include 
class my_exc : public runtime_error {
 public:
  my_exc ( const string &err ) : runtime_error (err ) {}
  // there, you can add more methods here.
  // remember, you can't add data members any more here
  // than you can add them to exception derived classes though.
};

Get it? Got it? Good.

2 Comments »

  1. I would like to comment that there is quite a lot to read about the purpose and usage of the exception inhertiance hiearchy in the C++ Standard.

    Thank you for a nice posting.

    Comment by jansson — May 15, 2009 @ 2:54 am

  2. Hi,

    1. Constructors are never virtual, I think you mean the assignment operator.

    2. Since you are catching a base class exception reference or a pointer u really do not need to overload the assignment operator. I think you are trying
    catch(std::exception e) which is not the right way to do it.

    3. The runtime_error uses std::string as a member variable.

    Ramesh

    Comment by rk — January 13, 2010 @ 9:39 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress

css.php
%d bloggers like this: