Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Либерти Джесс. Освой самостоятельно С++ за 21 день. - royallib.ru.rtf
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2.55 Mб
Скачать

День 20 Контрольные вопросы

1. Что такое исключение?

Это объект, который создается в результате использования ключевого слова throw.

Этот объект является признаком возникновения исключительной ситуации и передается в стек вызовов первого оператора catch, который выполняет обработку этого исключения.

2. Для чего нужен блок try?

Блок try — это набор выражений программы, которые могут создавать исключительные ситуации.

3. Для чего используется оператор catch?

Оператор catch содержит сигнатуру типа исключения, которое он способен обработать. Оператор catch располагается сразу за блоком try и выполняет роль приемника исключения, сгенерированного внутри блока try.

4. Какую информацию может содержать исключение?

Исключение — это объект, способный содержать любую информацию, которую можно определить внутри класса, созданного пользователем.

5. Когда создается объект исключения?

Объекты исключений создаются при вызове ключевого слова throw.

6. Следует ли передавать исключения как значения или как ссылки?

Вообше исключения нужно передавать как ссылки. Если вы не собираетесь модифицировать содержимое объекта исключения, вам следует передать ссылку, определенную с помошью ключевого слова const.

7. Будет ли оператор catch перехватывать производные исключения, если он настроен на базовый класс исключения?

Да, если исключение будет передано как ссылка.

8. Если используются два оператора catch, один из которых настроен на базовое сообщение, а второй ~ на производное, то в каком порядке их следует расположить?

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

9. Что означает оператор catch(...)?

Оператор catch(...) будет перехватывать все исключения любого типа.

10. Что такое точка останова?

Это позиция в коде, в которой отладчик остановит выполнение программы.

Упражнения

 1. Запишите блок try и оператор catch для отслеживания и обработки простого исключения.

#include <iostream.h>

class OutOfMemory {};

int main()

{

   try

   {

      int *myInt = new int;

      if (myInt == 0)

         throw OutOfMemory();

   }

   catch (OutOfMemory)

   {

      cout << "Unable to allocate memory!\n";

   }

   return 0;

}

2. Добавьте в исключение, полученное в упражнении 1, переменную-член и метод доступа и используйте их в блоке оператора catch.

#include <iostream.h>

#include <stdio.h>

#include <string.h>

class OutOfMemory;

{

   public:

      OutOfMemory(char *):

      char>> GetString() { return itsString; }

   private:

      char>> itsString;

};

OutOfMemory::OutOfMemory(char * theType)

{

   itsString = new char[80];

   char warning[] = "Out Of Memory! Can't allocate room for: ";

   strncpy(itsString, warning,60);

   strncat(itsString,theType,19);

}

int main()

{

   try

   {

     int *myInt = new int;

     if (myInt == 0)

        throw OutOfMemory("int");

   }

   catch (OutOfMemory& t:heException)

   {

      cout << theException.GetString();

   }

   return 0;

}

3. Унаследуйте новое исключение от исключения, полученного в упражнении 2. Измените блок оператора catch таким образом, чтобы в нем происходила обработка как производного, так и базового исключений.

1: #include <iostream.h>

2:

3: // Абстрактный тип исключений

4: class Exception

5: {

6:    public:

7:       Exception(){}

8:       virtual ~Exceptiori(){}

9:       virtual void PrintError() = 0;

10: };

11:

12: // Производный класс для обработки проблем памяти

13: // Обратите внимание: в этом классе не производится выделение памяти

14: class OutOfMemory : public Exception

15: {

16:    public:

17:       OutOfMemory(){}

18:       ~OutOfMemory(){}

19:       virtual void PrintError();

20:    private:

21: };

22:

23: void OutOfMemory::PrintError()

24: {

25:    cout << "Нет памяти !!\n";

26: }

27:

28: // Производный класс для обработки ввода неверных чисел

29: class RangeError : public Exception

30: {

31:    public:

32:       RangeError(unsigned long number){badNumber = number:}

33:       ~RangeError(){}

34:       virtual void PrintError();

35:       virtual unsigned long GetNumber() { return badNumber; }

36:       virtual void SetNumber( unsigned long number) {badNumber = number;}

37:    private:

38:       unsigned long badNumber;

39: };

40:

41: void RangeError::PrintError()

42: {

43:    cout << "Number out of range. You used " << GetNumber() << "N\n";

44: }

45:

46: void MyFunction(); // прототип функции

47:

48: int main()

49: {

50:    try

51:    {

52:       MyFunction();

53:    }

54:    // Чтобы использовать только один оператор catch,

55:    // примените для этого виртуальные функции

56:    catch (Exceptions theException)

57:    {

58:       theException.PrintError();

59:    }

60:    return 0;

61: }

62:

63: void MyFunction()

64: {

65:    unsigned int *myInt = new unsigned int;

66:    long testNumber;

67:    if (myInt == 0)

68:       throw 0ut0fMemory();

69:    cout << "Enter an int: ";

70:    cin >> testNumber;

71:    // эту проверку лучше заменить серией

72:    // проверок, чтобы выявить неверные данные, введенные пользователем

73:    if (testNumber > 3768 || testNumber < 0)

74:       throw RangeError(testNumber);

75:

76:    *mylnt = testNumber;

77:    cout << "Ok. myInt: " << *myInt;

78:    delete myInt;

79: }

4. Измените код из упражнения 3, чтобы получить трехуровневый вызов функции.

1: #include <iostream.h>

2:

3: // Абстрактный тип исключений

4: class Exception

5: {

6:    public:;

7:       Exception(){ }

8:       virtual ~Exception(){}

9:       virtual void PrintError() = 0;

10: };

11:

12: // Производный класс для обработки проблем памяти

13: // Обратите внимание: в этом классе не производится выделение памяти!

14: class OutOfMemory : public Exception

15: {

16:    public:

17:       OutOfMemory(){}

18:       ~OutOfMemory(){}

19:       virtual void PrintError();

20:    private:

21: };

22:

23: void OutOfMemory::PrintError()

24: {

25:    cout << "Нет памяти!!\n";

26: }

27:

28: // Производный класс для обработки ввода неверных чисел

29: class RangeError : public Exception

30: {

31:    public:

32:       RangeError(unsigned long number){badNumber = number;}

33:       ~RangeError(){ }

34:       virtual void PrintError();

35:       virtual unsigned long GetNumber() { return badNumber; }

36:       virtual void SetNumber(unsigned long number) {badNumber = number;}

37:    private:

38:       unsigned long badNumber;

39: };

40:

41: void RangeError::PrintError()

42: {

43:    cout << " Number out of range. You used " << GetNumber() << "!!\n";

44: }

45:

46: // прототипы функций

47: void MyFunction();

46: unsigned int * FunctionTwo();

49: void FunctionThree(unsigned int *);

50:

51: int main()

52: {

53:    try

54:    {

55:       MyFunction();

56:    }

57:    // Чтобы использовать только один оператор catch,

58:    // примените для этого виртуальные функции.

59:    catch (Exception& theException)

60:    {

61:       theException.PrintError();

62:    }

63:    return 0;

64: }

65:

66: unsigned int >> FunctionTwo()

67: {

68:    unsigned int <<royInt = new unsigned int;

69:    if (myInt == 0)

70:       throw OutOfMemory();

71:    return myInt;

72: }

73:

74: void MyFunction()

75: {

76:    unsigned int *myInt = FunctionTwo{ };

77:

78:    FunctionThree(myInt);

79:    cout << "0k. myInt: " << *myInt;

80:    delete myInt;

81: }

82:

83: void FunctionThree(unsigned int *ptr)

84: {

85:    long testNumber;

86:    cout << "Enter an int: ";

87:    cin >> testNumber;

88:    // эту проверку лучше заменить серией

89:    // проверок, чтобы выявить неверные данные, введенные пользователем

90:    if (testNumber > 3768 || testNumber < 0)

91:       throw RangeError(testNumber);

92:    *ptr = testNumber;

93: }

5. Жучки: что неправильно в следуюшем коде?

#include "string.h" // класс строк

class xOutOfMemory

{

   public:

      xOutOfMemory( const String& where ) : location( where ){ }

      ~xOutOfMemory(){ }

      virtual String where(){ return location };

   private:

      String location;

}

main()

{

   try

   {

      char *var = new char;

      if ( var == 0 )

         throw xOutOfMemory();

   }

   catch( xOutOfMemory& theException )

   {

      cout << "Out of memory at " << theException.location() << "\n";

   }

}

В процессе обработки ситуации нехватки памяти конструктором класса xOutOfMemory в области свободной памяти создается объект типа string. Это исключение может возникнуть только в том случае, когда программе не хватает памяти, поэтому попытка нового выделения памяти будет тем более неудачной.

Возможно, что попытка создать эту строку послужит причиной возникновения такого же исключения, что приведет к образованию бесконечного цикла, который будет выполняться до тех пор, пока компьютер не зависнет. Если эта строка все же нужна, можно выделить для нее память в статическом буфере до начала работы программы, а затем использовать ее rio необходимости, т.е. при возникновении исключения.