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 необходимости, т.е. при возникновении исключения.