I l@ve RuBoard | ![]() ![]() |
Item 12. Writing Exception-Safe Code—Part 5Difficulty: 7 All right, you've had enough rest—roll up your sleeves, and get ready for a wild ride. Now we're ready to delve a little deeper into the same example, and write not just one but two new-and-improved versions of Stack. Not only is it, indeed, possible to write exception-safe generic containers, but by the time this miniseries is over, we'll have created no fewer than three complete solutions to the exception-safe Stack problem. Along the way, we'll also discover the answers to several more interesting questions:
The answer to the last question may be quite different from what one might expect. Writing exception-safe containers in C++ isn't rocket science; it just requires significant care and a good understanding of how the language works. In particular, it helps to develop a habit of eyeing with mild suspicion anything that might turn out to be a function call—including user-defined operators, user-defined conversions, and silent temporary objects among the more subtle culprits—because any function call might throw.[9]
One way to greatly simplify an exception-safe container like Stack is to use better encapsulation. Specifically, we'd like to encapsulate the basic memory management work. Most of the care we had to take while writing our original exception-safe Stack was needed just to get the basic memory allocation right, so let's introduce a simple helper class to put all that work in one place. template <class T> class StackImpl { /*????*/: StackImpl(size_t size=0); ~StackImpl(); void Swap(StackImpl& other) throw(); T* v_; // ptr to a memory area big size_t vsize_; // enough for 'vsize_' T's size_t vused_; // # of T's actually in use private: // private and undefined: no copying allowed StackImpl( const StackImpl& ); StackImpl& operator=( const StackImpl& ); }; Note that StackImpl has all the original Stack's data members so that we've essentially moved the original Stack's representation entirely into StackImpl. StackImpl also has a helper function named Swap, which exchanges the guts of our StackImpl object with those of another StackImpl. Your tasks:
|
I l@ve RuBoard | ![]() ![]() |