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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«C++. Π‘Π±ΠΎΡ€Π½ΠΈΠΊ Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 86

Автор Π”. БтСфСнс

ΠšΡ€ΠΎΠΌΠ΅ пСрСмСщСния ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Π»Π΅Π½ΠΎΠ² Π² список ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 9.3 отличаСтся ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 9.2 Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΈΠΌ свойством. ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹-Ρ‡Π»Π΅Π½Ρ‹ Device Π½Π° этот Ρ€Π°Π· Π½Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π² динамичСской памяти с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° new. Π― сдСлал это для ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… особСнностСй, связанных с Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²-Ρ‡Π»Π΅Π½ΠΎΠ².

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, использованиС стСка вмСсто ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² динамичСской памяти позволяСт компилятору автоматичСски ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΈΡ… Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ. Если ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ выбрасываСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² Ρ…ΠΎΠ΄Π΅ конструирования, занимаСмая ΠΈΠΌ ΠΏΠ°ΠΌΡΡ‚ΡŒ автоматичСски освобоТдаСтся ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ раскрутки стСка Π² процСссС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ, Π»ΡŽΠ±Ρ‹Π΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ сконструированы, ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°ΡŽΡ‚ΡΡ, ΠΈ Π²Π°ΠΌ Π½Π΅ трСбуСтся ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ явно ΠΈΡ… ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ delete.

Но, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Π°ΠΌ трСбуСтся ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‡Π»Π΅Π½Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ (ΠΈΠ»ΠΈ с Π½ΠΈΠΌΠΈ Π²Ρ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ). Рассмотрим ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ классС Broker Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 9.2. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ваши ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½Π΅ Ρ‚Π°ΠΊ Π»ΠΈ?

class BrokerBad {

public:

 BrokerBad(int devno1, int devno2)

  try : dev1_(new Device(devno1)), // Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ динамичСской

   dev2_(new Device(devno2)) {}    // памяти Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

  catch (...) {

   if (dev1_) {

    delete dev1_; // He Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ

    delete dev2_; // являСтся ΠΏΠ»ΠΎΡ…ΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ, Ссли

   }              // всС ΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ

   throw; // ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ выбрасываниС Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ самого ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

  }

 ~BrokerBad() {

  delete dev1_;

  delete dev2_;

 }

private:

 BrokerBad();

 Device* dev1_;

 Device* dev2_;

};

НСт, Ρ‚Π°ΠΊ Π΄Π΅Π»Π°Ρ‚ΡŒ нСльзя. Π—Π΄Π΅ΡΡŒ Π΄Π²Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹. ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, это Π½Π΅ допустит ваш компилятор, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ располоТСнный Π² конструкторС Π±Π»ΠΎΠΊ catch Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌΡƒ ΠΊΠΎΠ΄Ρƒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ-Ρ‡Π»Π΅Π½Π°ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΡ… Π΅Ρ‰Π΅ Π½Π΅Ρ‚. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Π΄Π°ΠΆΠ΅ Ссли ваш компилятор позволяСт это Π΄Π΅Π»Π°Ρ‚ΡŒ, это Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ»ΠΎΡ…ΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ. Рассмотрим ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΈ конструировании ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° dev1_ выбрасываСтся ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. НиТС даСтся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π² catch-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅.

catch (...) {

 if (dev1_) { // КакоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ эта пСрСмСнная?

  delete dev1_; // Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π²Ρ‹ удаляСтС Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

  delete dev2_;

 }

 throw; // ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ выбрасываниС Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ самого ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

}

Если ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ выбрасываСтся Π² Ρ…ΠΎΠ΄Π΅ конструирования dev1_, Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ new Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ адрСс Π½ΠΎΠ²ΠΎΠ³ΠΎ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ участка памяти ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ dev1_ Π½Π΅ мСняСтся. Π’ΠΎΠ³Π΄Π° Ρ‡Ρ‚ΠΎ эта пСрСмСнная содСрТит? Она Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»Π°ΡΡŒ. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ станСтС Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ delete dev1_, Π²Ρ‹, вСроятно, ΠΏΠΎΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ нСдостовСрный адрСс, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΠΊΡ€Π°Ρ…Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π²Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΡƒΠ²ΠΎΠ»Π΅Π½Ρ‹, ΠΈ Π²Π°ΠΌ придСтся ΠΆΠΈΡ‚ΡŒ с этим ΠΏΠΎΠ·ΠΎΡ€ΠΎΠΌ всю ΠΎΡΡ‚Π°Π²ΡˆΡƒΡŽΡΡ Тизнь.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ΅ фиаско, ΠΊΡ€ΡƒΡ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‰Π΅Π΅ Π²Π°ΡˆΡƒ Тизнь, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠΉΡ‚Π΅ Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ваши ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ NULL ΠΈ Π·Π°Ρ‚Π΅ΠΌ создавайтС Π² конструкторС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ. Π’ этом случаС Π±ΡƒΠ΄Π΅Ρ‚ Π»Π΅Π³Ρ‡Π΅ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ подчистку, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ допускаСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ delete для NULL-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ.

BrokerBetter(int devno1, int devno2) :

 dev1_(NULL), dev2_(NULL) {

  try {

   dev1_ = new Device(devno1);

   dev2_ = new Device(devno2);

  } catch (...) {

   delete dev1_; // Π­Ρ‚ΠΎ сработаСт Π² любом случаС

   throw;

  }

 }

Π˜Ρ‚Π°ΠΊ, Π²Ρ‹ΡˆΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄Ρ‹Ρ‚ΠΎΠΆΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ: Ссли Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π»Π΅Π½Ρ‹-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ NULL Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ Π·Π°Ρ‚Π΅ΠΌ выдСляйтС Π² конструкторС ΠΏΠ°ΠΌΡΡ‚ΡŒ для ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π±Π»ΠΎΠΊ try/catch. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π² catch-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅. Однако, Ссли допускаСтся Ρ€Π°Π±ΠΎΡ‚Π° с автоматичСскими Ρ‡Π»Π΅Π½Π°ΠΌΠΈ, сконструируйтС ΠΈΡ… Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ синтаксис Π±Π»ΠΎΠΊΠ° try/catch для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π»ΡŽΠ±Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ.

Π‘ΠΌΠΎΡ‚Ρ€ΠΈ Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚ 9.2.

9.4. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ бСзопасных ΠΏΡ€ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ²

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

БоздаСтся функция-Ρ‡Π»Π΅Π½ ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΈ строгиС Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ Π΅Π΅ бСзопасности ΠΏΡ€ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΡ…, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ отсутствиС ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ рСсурсов ΠΈ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ нСдопустимоС состояниС Π² Ρ‚ΠΎΠΌ случаС, Ссли выбрасываСтся ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

РСшСниС

НСобходимо Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π±Ρ€Π°ΡΡ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, ΠΈ слСдуСт Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΡ… ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Ρ Π² Π±Π»ΠΎΠΊ try/catch. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π±Ρ€Π°ΡΡ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 9.4 ΠΏΠΎΠΊΠ°Π·Π°Π½ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· способов обСспСчСния бСзопасности Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° ΠΏΡ€ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΡ….

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 9.4. БСзопасная ΠΏΡ€ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΡ… функция-Ρ‡Π»Π΅Π½

class Message {

public:

 Message(int bufSize = DEFAULT_BUF_SIZE) :

  bufSize_(bufSize), initBufSize_(bufSize), msgSize_(0), buf_(NULL) {

  buf_ = new char[bufSize];

 }

 ~Message() {

  delete[] buf_;

 }


 // Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΠΊΠΎΠ½Π΅Ρ† ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅

 void appendData(int len, const char* data) {

  if (msgSize_+len > MAX_SIZE) {

   throw out_of_range("Data size exceeds maximum size.");

  }

  if (msgSize_+len > bufSize_) {

   int newBufSize = bufSize_;

   while ((newBufSize *= 2) < msgSize_+len);

   char* p = new char[newBufSize]; // Π’Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ

                                   // для Π½ΠΎΠ²ΠΎΠ³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π°

   copy(buf_, buf_+msgSize_, p);     // Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ старыС Π΄Π°Π½Π½Ρ‹Π΅

   copy(data, data+len, p+msgSize_); // Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅

   msgSize_ += len;

   bufSize_ = newBufSize;

   delete[] buf_; // Освободись старый Π±ΡƒΡ„Π΅Ρ€ ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π°

   buf_ = p;      // Π½ΠΎΠ²Ρ‹ΠΉ Π±ΡƒΡ„Π΅Ρ€

  } else {

   copy(data, data+len, buf_+msgSize_);

   msgSize_ += len;

  }

 }


 // Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² Π±ΡƒΡ„Π΅Ρ€ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

 int getData(int maxLen, char* data) {

  if (maxLen < msgSize_) {

   throw out_of_range("This data is too big for your buffer.");

  }

  copy(buf_, buf_+msgSize_, data);

  return(msgSize_);

 }


private:

 Message(const Message& orig) {}           // ΠœΡ‹ рассмотрим эти ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹

 Message& operator=(const Message& rhs) {} // Π² Ρ€Π΅Ρ†Π΅ΠΏΡ‚Π΅ 9.5

 int bufSize_;

 int initBufSize_;

 int msgSize_;

 char* buf_;

};

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 9.4 класс Message являСтся классом, содСрТащим ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅; Π²Ρ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² качСствС ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ тСкстовых ΠΈΠ»ΠΈ Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ систСмы Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ. Π—Π΄Π΅ΡΡŒ нас интСрСсуСт функция-Ρ‡Π»Π΅Π½ appendData, которая добавляСт Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ, Π² ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…, ΡƒΠΆΠ΅ находящихся Π² Π±ΡƒΡ„Π΅Ρ€Π΅, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ увСличивая ΠΏΡ€ΠΈ нСобходимости Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π°. Π—Π΄Π΅ΡΡŒ обСспСчиваСтся строгая гарантия бСзопасности этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° ΠΏΡ€ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΡ…, хотя Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ совсСм понятно, Ρ‡Π΅ΠΌ это достигаСтся.

Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ appendData.

if (msgSize_+len > bufSize_) {

 int newBufSize = bufSize_;

 while ((newBufSize *= 2) < msgSize_+len);

 char* p = new char[newBufSize];

Π­Ρ‚ΠΎΡ‚ Π±Π»ΠΎΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° обСспСчиваСт ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π±ΡƒΡ„Π΅Ρ€Π°. Π― Π΅Π³ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°ΡŽ ΠΏΡƒΡ‚Π΅ΠΌ удвоСния Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ Π½Π΅ станСт достаточно большим. Π­Ρ‚ΠΎΡ‚ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° бСзопасСн, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ здСсь Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° new, ΠΈ я Π½Π΅ обновляю состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ Π½Π΅ Π²Ρ‹Π΄Π΅Π»ΡΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½ΠΈ ΠΏΠΎΠ΄ ΠΊΠ°ΠΊΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ рСсурсы Π΄ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π΅Π³ΠΎ выполнСния. Π­Ρ‚ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ выбросит ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ bad_alloc, Ссли опСрационная систСма Π½Π΅ смоТСт Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ участок памяти Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°.

ПослС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ распрСдСлСния памяти я ΠΌΠΎΠ³Ρƒ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ состояния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, копируя Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ обновляя значСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…-Ρ‡Π»Π΅Π½ΠΎΠ².

copy(buf_, buf_+msgSize_, p);

copy(data, data+len, p+msgSize_);

msgSize_ += len;

bufSize_ = newBufSize;

delete[] buf_;

buf_ = p;

Ни ΠΎΠ΄Π½Π° ΠΈΠ· этих ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, поэтому Π½Π°ΠΌ Π½Π΅ ΠΎ Ρ‡Π΅ΠΌ Π²ΠΎΠ»Π½ΠΎΠ²Π°Ρ‚ΡŒΡΡ. (Π­Ρ‚ΠΎ происходит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±ΡƒΡ„Π΅Ρ€ прСдставляСт собой ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ символов; Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°Π·ΡŠΡΡΠ½Π΅Π½ΠΈΡ Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ ΠΏΡ€ΠΈ обсуТдСнии ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 9.5.)