How to throw good exceptions?

前端 未结 12 1351
情话喂你
情话喂你 2020-12-14 21:05

I heard you should never throw a string because there is a lack of information and you\'ll catch exceptions you dont expect to catch. What are good practice for throwing exc

相关标签:
12条回答
  • 2020-12-14 21:41

    Throwing pointers is probably not a good thing, as it complicates ownership of the thrown object. Class type exceptions are probably better than fundamentals simply because they can contain more information about the reason for the exception.

    In using a class or class hierarchy there are a couple of points you should consider:

    1. Both the copy constructor and destructor of the exception object must never throw an exception. If they do you're program will terminate immediately.(ISO 15.5/1)

    2. If your exception objects have base classes, then use public inheritance.
      A handler will only be selected for a derived to base class if the base class is accessible.(ISO 15.3/3)

    3. Finally, (for all exception types) ensure that the expression being thrown cannot itself result in an exception being thrown.

    For example:

    class Ex {
    public:
      Ex(int i) 
      : m_i (i)
      {
        if (i > 10) {
          throw "Exception value out of range";
        }
      }
    
      int m_i;
    };
    
    
    void foo (bool b) {
      if (! b) {
         // 'b' is false this is bad - throw an exception
         throw Ex(20);    // Ooops - throw's a string, not an Ex
      }
    }
    
    0 讨论(0)
  • 2020-12-14 21:44

    One basic thing is to reserve exceptions for exceptional situations only. Don't use them for flow control. For instance, "file not found" should not be an exception, it should be an error code or return value (unless the file is something that must exist, e.g. a configuration file). But if a file suddenly disappears while you're processing it, then throwing an exception is a good choice.

    When exceptions are used sparingly, you don't need to turn your code into a try-catch -spaghetti in order to avoid receiving incomprehensible-in-the-context exceptions from the deeper layers.

    0 讨论(0)
  • 2020-12-14 21:49

    If you're throwing exceptions from a component other developers will be using downstream, please do them a big favour and always derive your own exception classes (if you really need them c.f using the standard exceptions) from std::exception. Avoid at all costs utter abominations like throwing ints, HRESULTS, char*, std::string...

    0 讨论(0)
  • 2020-12-14 21:52

    Use the standard exceptions! If you have a specific error, try to avoid it with return value. If you have to use exceptions, define your custom exception that inherits from Exception and create a custom message.

    0 讨论(0)
  • 2020-12-14 21:52

    Sometimes it can happen that you're not able to return error code eg. when you need exact context of when error situation occured, eg. when you need to propagate error status 3 levels up - you loose context.

    In this situation custom class is the best solution. I use this approach, defining my own inline classes (there's no .cpp for them; only .h) eg.:

    class DeviceException {
        ;
    }
    
    class DeviceIOException: public DeviceException {
        DeviceIOException(std::string msg, int errorCode);
    }
    

    etc.

    I then can judge/act upon the exception by type and by information contained within.

    0 讨论(0)
  • 2020-12-14 21:55

    I always throw an exception with a message of where it occurred and what caused it to happen:

    throw NException("Foo::Bar", "Mungulator cause a stack overflow!");
    

    You can then use these strings in messageboxes etc.

    I always catch via

    catch (NException& ex) { ... }
    

    If you running windows you can pass the error value and have a function derive the error message. The best example of this is in Windows via C/C++ by Jeffrey Richter.

    0 讨论(0)
提交回复
热议问题