Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 20.1. Возникновение исключительной ситуации






1: #include < iostream.h>

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< < (ostream&, const Array&);

23:

24: class xBoundary { }; // определяем класс исключений

25: private:

26: int *pType;

27: int itsSize;

28: };

29:

30:

31: Array:: Array(intsize):

32: itsSize(size)

33: {

34: рТуре = new int[size];

35: for (int i = 0; i< size; i++)

36: pType[i] = 0;

37: }

38:

39:

40: Array& Array:: operator=(const Array & rhs)

41: {

42: if (this == & rhs)

43: return *thts;

44: delete [] pType;

45: itsSize = rhs.GetitsSiza();

46: pType = new int[itsSize];

47: for (int i = 0; i< itsSize; i++)

48: pType[i] = rhs[i];

49: return *this;

50: }

51:

52: Array:: Array(const Array & rhs)

53: {

54: itsSize = rhs.GetitsSize();

55: pType = new int[itsSize];

56: for (int i = 0; i< itsSize; i++)

57: pType[i] = rhs[i];

58: }

59:

60:

61: int& Array:: operator[](int offSet)

62: {

63: int size = GetitsSize();

64: if (offSet > = 0 & & offSet < GetitsSize())

65: return pType[offSet];

66: throw xBoundary();

67: return pType[0]; // требование компилятора

68: }

69:

70:

71: const int& Array:: operator[](int offSet) const

72: {

73: int mysize = GetitsSize();

74: if (offSet > = 0 & & offSet < GetitsSize())

75: return pType[offSet];

76: throw xBoundary();

77: return pType[0]; // требование компилятора

78: }

79:

80: ostream& operator< < (ostream& output, const Array& theArray)

81: {

82: for (int i = 0; i< theArray, GetitsSize(); i++)

83: output < < " [" < < i < < " ] " < < theArray[i] < < endl;

84: return output;

85: }

86:

87: int main()

88: {

89: Array intArray(20);

90: try

91: {

92: for (int ] < < 0; j< 100; j++)

93: {

94: intArray[j] = j;

95: cout < < " intArray[" < < j < < " ] okay..." < < endl;

96: }

97: }

98: catch (Array:: xBoundary)

99: {

100: cout < < " Unable to process your input! \n";

101: }

102: cout < < " Done.\n";

103: return 0;

104: }

 

Результат:

intArray[0] okay...

intArray[1] okay...

intArray[2] okay...

intArray[3] okay...

intArray[4] okay...

intArray[5] okay...

intArray[6] okay...

intArray[7] okay...

intArray[8] okay...

intArray[9] okay...

intArray[10] okay...

intArray[11] okay...

intArray[12] okay...

intArray[13] okay...

intArray[14] okay...

intArray[15] okay...

intArray[16] okay...

intArray[17] okay...

intArray[18] okay...

intArray[19] okay...

Unable to process your input!

Done.

 

Анализ: В листинге 20.1 представлен несколько усеченный класс Array, основанный на шаблоне, разработанном на занятии 19.

В строке 24 объявляется новый класс xBoundary внутри объявления внешнего класса Array.

В этом новом классе ни по каким внешним признакам нельзя узнать класс обработки исключительных ситуаций. Он чрезвычайно прост и не содержит никаких данных и методов. Тем не менее это вполне работоспособный класс.

На самом деле было бы неправильно говорить, что он не содержит никаких методов, потому что компилятор автоматически назначает ему стандартный конструктор, деструктор, конструктор-копировщик и оператор присваивания (=), поэтому у него фактически есть четыре метода, но нет данных.

Обратите внимание на то, что его объявление внутри класса Array служит только для объединения двух классов. Как описано в главе 15, класс Array не имеет никакого особого доступа к классу xBoundary, да и класс xBoundary не наделен преимущественным доступом к членам класса Array.

В строках 61—68 и 71—78 операторы индексирования ([]) замещены таким образом, чтобы предварительно анализировать введенный индекс смещения и, если оно окажется вне допустимого диапазона, обратиться к классу xBoundary для создания исключения. Назначение круглых скобок состоит в том, чтобы отделить обращение к конструктору класса xBoundary от использования константы перечисления. Обратите внимание, что некоторые компиляторы компании Microsoft требуют, чтобы определение функции в любом случае заканчивалось строкой с оператором return, согласующейся по типу с прототипом функции (в данном случае возвращение ссылки на целочисленное значение), несмотря на то что в случае возникновения исключительной ситуации в строке 66 выполнение программы никогда не достигнет строки 67. Этот пример говорит о том, что логические ошибки не чужды даже компании Microsoft!

В строке 90 ключевым словом try начинается блок отслеживания исключительных ситуаций, который оканчивается в строке 97. Внутри этого блока в массив, объявленный в строке 89, добавляется 101 целое число.

В строке 98 объявлен блок catch для перехвата исключений класса xBoundary.

В управляющей программе в строках 87—104 создается блок try, в котором инициализируется каждый член массива. Когда переменная j (строка 92) увеличится до 20, осуществляется доступ к члену, соответствующему смещению 20. Это приводит к невыполнению условия проверки в строке 64, в результате чего замещенный оператор индексирования operator[] генерирует исключение класса xBoundary (строка 66).

Управление программой передается к блоку catch в строке 98, и исключение перехватывается или обрабатывается оператором catch в той же строке, которая печатает сообщение об ошибках. Программа доходит до конца блока catch в строке 100.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.