There are something in exception handling that is not easy apprehensible for most readers, so here is the discussion on some specific of the exception handlings.
the code that the example below will use to illustrate is as follow.
#include <iostream> #include <string> using std::cout; using std::cerr; using std::endl; using std::string; class Excp { public : // print error message static void print(string msg) { cerr << msg << endl; } }; class popOnEmpty : public Excp { }; class pushOnFull: public Excp { public: pushOnFull(int value ) {} ; }; class iStack { public: void push(int value); bool full() { return true ; } };
so suppose that we have a throw expression as follow.
void iStack::push(int value) { if (full() ) { // value stored in exception object throw pushOnFull(value); } }
there are actually a lots of things happening underneath.
many stap take place as a consequence of executing this throw exception
you may wonder why the step 2 is needed and why an expression object is created -
the expression pushOnFull(value);
create a temporary boject that is destroyed at the end of throw expression. The exception, however must last until a handler has been found, which may be many functions further up the chain
of the function calls. It is therefore necessary to copy the temporary object into a storage location, called the exception object, that is guaranteed to last until the exception hass ben handled
however, this a classic way how how an exception is constructed, but in some cases it may be possible for the implementation to create the exception object directly, without creating the temporary object in step 1, however, this temporary elinimation is not required or always possible.
another tripwire/pitfall/trap that people falls is when handling exception when pointer is concerned.
here is the code.
void iStack::push(int value) { if (full()) { pushOnFull except(value); Excp *pse = &except; throw *pse; // exception object has type Excp } }
because of the discussion we had before, since the dereference will return the type of object what the pionter points to, so the return value is of type Excp... even though the pointer actually point to a more derived class object , the actualy type is not examined to create the exception object
the implied restriction on the kind of classes that can be used to create exception objects, the throw exception in the iStack member function push() is in error if