I l @ ve RuBoard |
Function try blocks were added to C++ to slightly enlarge the scope of exceptions that a function can catch. This Item covers
For convenience, throughout this Item, member means "nonstatic class data member" unless otherwise noted. Function Try Blocks
// Example 17-1 // class C : private A { B b_; }; In the C constructor, how can you catch an exception thrown from the constructor of a base subobject (such as A ) or a member object (such as b_ )? That's what function try blocks are for: // Example 17-1(a): Constructor function try block // C::C() try : A ( /*...*/ ) // optional initialization list , b_( /*...*/ ) { } catch( ... ) { // We get here if either A::A() or B::B() throws. // If A::A() succeeds and then B::B() throws, the // language guarantees that A::~A() will be called // to destroy the already-created A base subobject // before control reaches this catch block. } The more interesting question, though, is: Why would you want to do this? That question brings us to the first of two key points in this Item. Object Lifetimes and What a Constructor Exception MeansIn a moment, we'll consider the question of whether the above C constructor can, or should, absorb an A or B constructor exception and emit no exception at all. But before we can answer that question correctly, we need to make sure we fully understand object lifetimes [1] and what it means for a constructor to throw an exception.
// Example 17-2 // { Parrot p; } When does the object's lifetime begin? When does it end? Outside the object's lifetime, what is the status of the object? Finally, what would it mean if the constructor threw an exception? Let's take the questions one at a time:
Kidding aside, the important point here is that the state of the object before its lifetime begins is exactly the same as after its lifetime ends: There is no object, period. This observation brings us to the next key question:
Incidentally, this is why a destructor will never be called if the constructor didn't succeed ”there's nothing to destroy. It cannot die, for it never lived. Note that this makes the phrase "an object whose constructor threw an exception" really an oxymoron. Such a thing is even less than an ex-object. It never lived, never made it to objecthood. It is a non-object. We might summarize the C++ constructor model as follows : Either:
There are no other possibilities. Armed with this information, we can now better tackle the next Item's question: What about absorbing exceptions? |
I l @ ve RuBoard |