Try this with a number of values for the size of the array. Then try putting in –5. You
might have expected xNegativeto be called, but the order of the tests in the constructor
prevented this:size < 10was evaluated before size < 1. To fix this, swap lines 61 and
62 with lines 65 and 66 and recompile.
732 Day 20
After the constructor has been invoked, memory has been allocated for the
object. Therefore, throwing any exception from the constructor can leave
the object allocated but unusable. Generally, you should wrap the construc-
tor in a try/catch, and if an exception occurs, mark the object (internally) as
unusable. Each member function should check this “valid” flag to be certain
additional errors won’t occur when someone uses an object whose initializa-
tion was interrupted.
TIP
Exception Hierarchies ....................................................................................
Exceptions are classes, and as such, they can be derived from. It might be advantageous
to create a class xSize, and to derive from it xZero,xTooSmall,xTooBig, and
xNegative. Thus, some functions might just catch xSizeerrors, and other functions
might catch the specific type of xSizeerror. Listing 20.6 illustrates this idea.
LISTING20.6 Class Hierarchies and Exceptions
0: #include <iostream>
1: using namespace std;
2:
3: const int DefaultSize = 10;
4:
5: class Array
6: {
7: public:
8: // constructors
9: Array(int itsSize = DefaultSize);
10: Array(const Array &rhs);
11: ~Array() { delete [] pType;}
12:
13: // operators
14: Array& operator=(const Array&);
15: int& operator[](int offSet);
16: const int& operator[](int offSet) const;
17:
18: // accessors
19: int GetitsSize() const { return itsSize; }
20: