9: Array(int itsSize = DefaultSize);
10: Array(const Array &rhs);
11: ~Array() { delete [] pType;}
12:
13: // операторы
14: Array& operator=(const Array&);
15: int& operator[](int offSet);
16: const int& operator[](int offSet) const;
17:
18: // методы доступа
19: int GetitsSize() const { return itsSize; }
20:
21: // функция-друг
22: friend ostream& operator<< (ostream&, const Array&);
23:
24: // определение классов исключений
25: class xBoundary { };
26: class xSize
27: {
28: public:
29: xSize(int size):itsSize(size) { }
30: ~xSize(){ }
31: int GetSize() { return itsSize; }
32: private:
33: int itsSize;
34: };
35:
36: class xTooBig : public xSize
37: {
38: public:
39: xTooBig(int size):xSize(size){ }
40: };
41:
42: class xTooSmall : public xSize
43: {
44: public:
45: xTooSmall(int size):xSize(size){ }
46: };
47:
48: class xZero : public xTooSmall
49: {
50: public:
51: xZero(int size):xTooSmall(size){ }
52: };
53:
54: class xNegative : public xSize
55: {
56: public:
57: xNegative(int size):xSize(size){ }
58: };
59:
60: private:
61: int *pType;
62: int itsSize;
63: };
64:
65:
66: Array::Array(int size):
67: itsSize(size)
68: {
69: if (size == 0)
70: throw xZero(size);
71: if (size > 30000)
72: throw xTooBig(size);
73: if (size <1)
74: throw xNegative(size);
75: if (size < 10)
76: throw xTooSnall(size);
77:
78: pType = new int[size];
79: for (int i = 0; i
80: pType[i] = 0;
81: }
82:
83:
84: int& Array::operator[] (int offSet)
85: {
86: int size = GetitsSize();
87: if (offSet >= 0 && offSet < GetitsSize())
88: return pType[offSet];
89: throw xBoundary();
90: return pType[0];
91: }
92:
93: const int&Array::operator[] (int offSet) const
94: {
95: int size = GetitsSize();
96: if (offSet >= 0 && offSet < GetitsSize())
97: return pType[offSet];
98: throw xBoundary();
99: return pType[0];
100: }
101:
102: int main()
103: {
104:
105: try
106: {
107: Array intArray(9);
108: for (int j = 0; j< 100; j++)
109: {
110: intArray[j] = j;
111: cout << "intArray[" << j << "] okay..." << endl;
112: }
113: }
114: catch (Array::xBoundary)
115: {
116: cout << "Unable to process your input!\n";
117: }
118: catch(Array::xZero theException)
119: {
120: cout << "You asked for an Array of zero objectsl " << endl;
121: cout << "Received " << theExesptiQn,GatSize() << endl;
122: }
123: catch (Array:;xTooBig theException)
124: {
125: cout << "This Array is too big,,, " << endl;
126: cout << "Received " << theException,GetSize() << endl;
127: }
128: catch (Array;:xTooSmall theException)
129: {
130: cout << "This Array is too small... " << endl;
131: cout << "Received " << theException.GetSize() << endl;
132: }
133: catch (...)
134: {
135: cout << "Something went wrong, but I've no idea what!\n";
136: }
137: cout << "Done.\n";
138: return 0;
139: }
Результат:
This array is too small...
Received 9
Done.
Анализ:Объявление класса xSize было изменено таким образом, чтобы включить в него переменную-член itsSize (строкаЗЗ) и функцию-член GetSize() (строка 31). Кроме того, был добавлен конструктор, который принимает целое число и инициализирует переменную-член, как показано в строке 29.
Производные классы объявляют конструктор, который лишь инициализирует базовый класс. При этом никакие другие функции объявлены не были (частично из экономии места в листинге).
Операторы catch в строках 114-136 изменены таким образом, чтобы создавать именованный объект исключения (thoException), который используется в теле блока catch для доступа к данным, сохраняемым в переменной-члене itsSize.
Примечание: При работе с исключениями следует помнить об их сути: если уж оно возникло, значит, что-то не в порядке с распределением ресурсов, и обработку этого исключения нужно записать таким образом, чтобы вновь не создать ту же проблему. Следовательно, если вы создаете исключение OutOfMemory, то не стоит а конструкторе этого класса пытаться выделить память для какого-либо объекта.
Весьма утомительно писать вручную все эти конструкции с операторами oatch, каждый из которых должен выводить свое сообщение. Тем более, что при увеличении объема программы стремительно возрастает вероятность возникновения в ней ошибок. Лучше переложить эту работу на объект исключения, который сам должен определять тип исключения и выбирать соответствующее сообщение. В листинге 20.5 для решения этой проблемы использован подход, который в большей степени отвечает принципам объектно-ориентированного программирования. В классах исключений применяются виртуальные функции, обеспечивающие полиморфизм объекта исключения.
Листинг 20.5. Передача аргументов как ссылок u использование виртуальных функций в классах исключений
1: #include
2:
3: const int DefaultSize = 10;
4:
5: class Array
6: {
7: public:
8: // конструкторы
9: Array(int itsSize = DefaultSize);
10: Array(const Array &rhs);
11: ~Array() { delete [] pType;}
12:
13: // операторы
14: Array& operator=(const Array&);
15: int& operator[](int offSet);
16: const int& operator[](int offSet) const;
17:
18: // методы доступа
19: int GetitsSize() const { return itsSize; }
20:
21: // функция-друг
22: friend ostream& operator<<
23: (ostream&, const Array&);
24:
25: // определение классов исключений
26: class xBoundary { };
27: class xSize
Читать дальше