Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «Освой ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π‘++ Π·Π° 21 дСнь.Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 149

Автор ДТСсс Π›ΠΈΠ±Π΅Ρ€Ρ‚ΠΈ

Листинг 21.6. Π’Ρ‹Π²ΠΎΠ΄ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ

1: // Листинг 21.6. Π’Ρ‹Π²ΠΎΠ΄ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ

2: #include <iostream.h>

3: #define DEBUG

4:

5: #ifndef DEBUG

6: #define PRINT(x)

7: #else

8: #define PRINT(x) \

9:    cout << #x << ":\t" << x << endl;

10: #endif

11:

12: enum bool { FALSE, TRUE } ; 13:

14: int main()

15: {

16:    int x = 5;

17:    long Ρƒ = 738981;

18:    PRINT(x);

19:    for (int i = 0; i < x; i++)

20:    {

21:       PRINT(i);

22:    }

23:

24:    PRINT (Ρƒ);

25:    PRINT("Hi,");

26:    int *px = &x;

27:    PRINT(px);

28:    PRINT (*px);

29:    return 0;

30: }


Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

x: 5

i: 0

i: 1

i: 2

i: 3

i: 4

Ρƒ: 73898

"Hi.": Hi.

px: 0x2100

*px: 5


Анализ: ΠœΠ°ΠΊΡ€ΠΎΡ PRINT(x) (строки 5β€”10) Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Π²Ρ‹Π²ΠΎΠ΄ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ значСния ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ сначала ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ cout пСрСдаСтся сам ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, взятый Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, Ρ‚.Π΅., Ссли Π²Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΡ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ x, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ cout ΠΏΡ€ΠΈΠΌΠ΅Ρ‚ "x".

Π—Π°Ρ‚Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ cout ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΡƒΡŽ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ строку ":\t", которая обСспСчиваСт ΠΏΠ΅Ρ‡Π°Ρ‚ΡŒ двоСточия ΠΈ табуляции. ПослС этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ cout ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° (x), Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ endl выполняСт ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π½Π° Π½ΠΎΠ²ΡƒΡŽ строку ΠΈ ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ Π±ΡƒΡ„Π΅Ρ€.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Ρƒ вас вмСсто значСния 0x2100 ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π²Π΅Π΄Π΅Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ число.

Π£Ρ€ΠΎΠ²Π½ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ

Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΈ слоТных ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… Π²Π°ΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, понадобится большС Ρ€Ρ‹Ρ‡Π°Π³ΠΎΠ² управлСния для отлаТивания ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ‡Π΅ΠΌ просто ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π΅ΠΆΠΈΠΌΠ° ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ (ΠΏΡƒΡ‚Π΅ΠΌ опрСдСлСния лСксСмы DEBUG). Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ ΡƒΡ€ΠΎΠ²Π½ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ тСстированиС для этих ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ, принимая Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΌΠ°ΠΊΡ€ΠΎΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Π° ΠΊΠ°ΠΊΠΈΠ΅ - ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ, достаточно послС выраТСния #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 GetLen()const { 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:      {

136:         ASSERT(Invariants());

137:         return itsString[itsLen-1];

138:      }

139:      else

140:      {

141:         ASSERT(Invariants());

142:         return itsString[offset];

143:      }

144:   }

145:   // константный ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ индСксирования

146:   char String::operator[](int offset) const

147:   {

148:      ASSERT(Invariants());

149:      char retVal;

150:      if (offset > itsLen)

151:         retVal = itsString[itsLen-1];

152:      else

153:         retVal = itsString[offset];

154:      ASSERT(Invariants());

155:      return retVal;

156:   }

157:

158:   bool String::Invariants() const

159:   {

160:      PRINT("(String Invariants Checked)");

161:      return ( (bool) (itsLen && itsString) ||

162:         (!itsLen && !itsString) );

163:   }

164:

165:   class Animal

166:   {

167:      public:

168:         Anxmal():itsAge(1),itsName("John Q, Animal")

169:            { ASSERT(Invariants());}

170:

171:         Animal(int, const String&);

172:         ~Animal(){ }

173:

174:         int GetAge()

175:         {

176:            ASSERT(Invariants());

177:            return itsAga;

178:         }

179:

180:         void SetAge(int Age)

181:         {

182:            ASSERT(Invariants());

183:            itsAge = Age;

184:            ASSERT(Inva riants());

185:         }

186:         String& GetName()

187:         {

188:            ASSERT(Invariants());

189:            return itsName;

190:         }

191:

192:         void SetName(const String& name)

193:         {

194:            ASSERT(Invariants());

195:            itsName = name;

196:            ASSERT(Invariants());

197:         }

198:

199:         bool Invariants();

200:      private:

201:         int itsAge;

202:         String itsName;

203:   }

204:

205:   Animal::Animal(int age, const String& name):

206:   itsAge(age),

207:   itsName(name)

208:   {

209:      ASSERT(Invariants());

210:   }

211:

212:   bool Animal::Invariants()

213:   {

214:      PRINT("(Animal Invariants Checked)");

215:      return (itsAge > 0 && itsName.GetLen());

216:   }

217:

218:   int main()

219:   {

220:      const int AGE = 5;

221:      EVAL(AGE);

222:      Animal sparky(AGE,"Sparky");

223:      cout << "\n" << sparky.GetName().GetStrin();

224:      cout << " is ";

225:      cout << sparky.GetAge() << " years old.";

226:      sparky.SetAge(8);

227:      cout << "\n" << sparky.GetName().GetString();

228:      cout << " is ";

229:      cout << sparky.GetAge() << " years old.";

230:      return 0;

231:   }


Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

AGE: 5

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

(String Invariants Checked)

Sparky is (Animal Invariants Checked)

5 years old. (Animal Invariants Checked)

(Animal Invariants Checked)

(Animal Invariants Checked)

Sparky is (Animal Invariants Checked)

8 years old. (String Invariants Checked)

(String Invariants Checked)

// run again with DEBUG = MEDIUM