Освой самостоятельно С++ за 21 день.
Шрифт:
Затем объект cout принимает заключенную в кавычки строку ":\t", которая обеспечивает печать двоеточия и табуляции. После этого объект cout принимает значение параметра (x), а объект endl выполняет переход на новую строку и очищает буфер.
Обратите внимание, что у вас вместо значения 0x2100 может быть выведено другое число.
Уровни отладки
В больших и сложных проектах вам, возможно, понадобится больше рычагов
Чтобы определить уровень отладки, достаточно после выражения #define DEBUG указать номер. Хотя число уровней может быть любым, обычная система должна иметь четыре уровня: HIGH (высокий), MEDIUM (средний), LOW (низкий) и NONE (никакой). В листинге 21.7 показано, как это можно сделать, на примере классов String и Animal из листинга 21.5.
Листинг 21.7. Уровни отладки
1: enum LEVEL { NONE, LOW, MEDIUM, HIGH } ;
2: const int FALSE = 0;
3: const int TRUE = 1;
4: typedef int bool;
5:
6: #define DEBUGLEVEL HIGH
7:
8: #include <iostream.h>
9: #include <string.h>
10:
11: #if DEBUGLEVEL < LOW // должен быть средний или высокий
12: #define ASSERT(x)
13: #else
14: #define ASSERT(x)
15: if (!(x))
16: {
17: cout << "ERROR!! Assert " << #x << " failed\n";
18: cout << " on line " << __LINE__ << "\n";
19: cout << " in file " << FILE << "\n";
20: }
21: #endif
22:
23: #if DEBUGLEVEL < MEDIUM
24: #define EVAL(x)
25: #else
26: #define EVAL(x)
27: cout << #x << ":\t" << x << andl;
28: #endif
29:
30: #if DEBUGLEVEL < HIGH
31: #define PRINT(x)
32: #else
33: #define PRINT(x)
34: cout << x << endl;
35: #endif
36:
37:
38: class String
39: {
40: public:
41: // конструкторы
42: String;
43: String(const char *const);
44: String(const String &);
45: ~String;
46:
47: char & operator[](int offset);
48: char operator[](int offset) const;
49:
50: String & operator= (const String &);
51: int GetLenconst { return itsLen; }
52: const char >> GetString const
53: { return itsString; }
54: bool Invariants const;
55:
56: private:
57: String (int); //
закрытый конструктор58: char * itsString;
59: unsigned short itsLen;
60: };
61:
62: // стандартный конструктор создает строку нулевой длины
63: String::String
64: {
65: itsString = new char[1];
66: itsString[0] = '\0';
67: itsLen=0;
68: ASSERT(Invariants);
69: }
70:
71: // закрытый (вспомогательный) конструктор, используемый
72: // методами класса только для создания новой строки
73: // требуемого размера. Заполняется символом Null.
74: String::String(int len)
75: {
76: itsString = new char[len+1];
77: for (int i = 0; i<=len; i++)
78: itsString[i] = '\0';
79: itsLen=len;
80: ASSERT(Invariants);
81: }
82:
83: // Преобразует массив символов к типу String
84: String::String(const char * const cString)
85: {
86: itsLen = strlen(cString);
87: itsString = new char[itsLen+1];
88: for (int i = 0; i<itsLen; i++)
89: itsString[i] = cString[i];
90: itsString[itsLen]='\0';
91: ASSERT(Invariants);
92: }
93:
94: // конструктор-копировщик
95: String::String (const String & rhs)
96: {
97: itsLen=rhs.GetLen;
98: itsString = new char[itsLen+1];
99: for (int i = 0; i<itsLen;i++)
100: itsString[i] = rhs[i];
101: itsString[itsLen] = '\0';
102: ASSERT(Invariants);
103: }
104:
105: // деструктор освобождает выделенную память
106: String::^String
107: {
108: ASSERT(Invariants);
109: delete [] itsString;
110: itsLen = 0;
111: }
112:
113: // оператор выполняет сравнение, освобождает занятую память
114: // затем копирует строку и ее размер
115: String& String::operator=(const String & rhs)
116: {
117: ASSERT(Invariants);
118: if (this == &rhs)
119: return *this;
120: delete [] itsString;
121: itsLen=rhs.GetLen;
122: itsString = new char[itsLen+1];
123: for (int i = 0; i<itsLen;i++)
124: itsString[i] = rhs[i];
125: itsString[itsLen] = '\0';
126: ASSERT(Invariants);
127: return *this;
128: }
129:
130: // неконстантный оператор индексирования
131: char & String:;operator[](int offset)
132: {
133: ASSERT(Invariants);
134: if (offset > itsLen)
135: {