Thread: Deriving from std::except

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Deriving from std::except

    I'm deriving from std::except to create my own exception handling classes that the application will use. unit_error below defines an error context much like std::logic_error does, for instance. However, unit_error (and order_error, output_error, army_error...) classes will focus on the object instead of the context surrounding its usage.
    Code:
    class unit_error: public std::exception {
    public:
       unit_error(const std::string& err, const unsigned int n): err_(err), errno_(n) {}
    
       virtual ~unit_error() throw() {}
    
       const char* what() const throw() { return err_.c_str(); }
       unsigned int error() const throw() { return errno_; }
    
    private:
       std::string err_;     // Holds error description
       unsigned int errno_;  // Holds error code
    
    };

    Three things are worrying me:

    First, does basic_string::c_str() throw? The compiler can't warn me about this and Lint says it does. However, digging in the library code (something I'm not very good at) I can't find any evidence it does. I guess I could program defensively and just do a try-catch inside what() and forget about it, but i'm curious anyway.

    Second, error codes are provided in the namespace "murk::error_codes" declared on the same header as these classes. These are const uint variables. However I wonder if there would be a better place to move them. More specificaly inside the exception handling classes as static const members? This way, each class could declare their own related errors and leave the others out.

    std::exception is not an abstract class. I can't see any problems with that since I can't imagine a plausible reason for users to want to assign mix-type error handling objects inside a catch clause. However, more often than not I cannot see past my nose, so is there a reason for concern? And what should I do about it? I'm stuck in finding a way if I have to deal with it. It is also possible other classes may derive from unit_error in the future.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >First, does basic_string::c_str() throw?
    It can. This is left as an implementation choice, so if you don't want an exception, you're better off working directly with C-style strings.

    >More specificaly inside the exception handling classes as static const members?
    That sounds like a better solution.

    >std::exception is not an abstract class.
    I don't see the problem. Can you describe the situation that you think would be problematic?
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    First, does basic_string::c_str() throw?
    In theory, yes. In practice... it really shouldn't. It is a pathological case, but consider the case that you have a basic_string<T> where T:perator= throws. On top of that, even for character strings it's possible that your library could potentially have to reallocate memory for c_str() because of not enough memory to append the terminator. I would just ignore these cases personally.

    std::exception is not an abstract class.
    You lost me there. Maybe you are using the phase 'abstract class' in a way I'm not familiar with? std::exception is abstract.

    I can't comment on the error_codes problem.
    Last edited by QuestionC; 06-22-2007 at 01:26 PM.
    Callou collei we'll code the way
    Of prime numbers and pings!

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Maybe you are using the phase 'abstract class' in a way I'm not familiar with? std::exception is abstract.
    An abstract class is a class that has at least one pure virtual function and thus, can't be instantiated. std::exception is not abstract.
    My best code is written with the delete key.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    However, it does have a virtual destructor and is therefore safe to use polymorphically. Just beware of slicing. Never catch by value!

    The c_str() issue is weird, especially as std::runtime_error and std::logic_error (from <stdexcept>) both take a std::string in the constructor, so presumably their what() also returns c_str().

    One way to do it would be this:
    Code:
    class my_error : public std::exception
    {
      std::string m_msg;
      const char *m_msg_cstr;
    public:
      my_error(const std::string &msg)
        m_msg(msg), m_msg_cstr(m_msg.c_str())
      {}
    
      const char *what() throw()
      {
        return m_msg_cstr;
      }
    
      // ...
    };
    There you go. At the additional expense of sizeof(void*), you have an exception-safe what().
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    That is definitively an improvement. Most helpful as usual. Thanks CornedBee.

    >>More specificaly inside the exception handling classes as static const members?
    > That sounds like a better solution.
    Thanks Prelude. I really wanted to simplify this but was wondering if it was advisable.

    >>std::exception is not an abstract class.
    >I don't see the problem. Can you describe the situation that you think would be problematic?

    I'll have to think of this a little bit more. There was something, but I can't recall now... I'll get back to this later...
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. wtf...? deriving from template
    By Raven Arkadon in forum C++ Programming
    Replies: 11
    Last Post: 06-28-2005, 02:36 AM
  2. Deriving one class from another
    By SpudNuts in forum C++ Programming
    Replies: 4
    Last Post: 02-08-2005, 02:15 AM
  3. Deriving from CEditView?
    By Jamsan in forum Windows Programming
    Replies: 1
    Last Post: 04-02-2003, 08:22 AM
  4. Deriving from ostream...
    By thynctank in forum C++ Programming
    Replies: 2
    Last Post: 09-30-2002, 03:39 PM
  5. Deriving from CWindow
    By xds4lx in forum Windows Programming
    Replies: 4
    Last Post: 02-22-2002, 05:12 PM