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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования C++. ΠŸΡΡ‚ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 174

Автор Π‘Ρ‚Π΅Π½Π»ΠΈ Π›ΠΈΠΏΠΏΠΌΠ°Π½

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.25. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ класса StrBlob, Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ Ρ‚Π°ΠΊΠΆΠ΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ shared_ptr, Ρ‡Ρ‚ΠΎΠ±Ρ‹ класс StrBlobPtr всС Π΅Ρ‰Π΅ ΠΌΠΎΠ³ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ weak_ptr для Π²Π΅ΠΊΡ‚ΠΎΡ€Π°. ΠŸΠ΅Ρ€Π΅Π΄Π΅Π»Π°Π½Π½Ρ‹ΠΉ класс Π±ΡƒΠ΄Π΅Ρ‚ Π½ΡƒΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π² конструкторС ΠΊΠΎΠΏΠΈΠΉ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ присвоСния ΠΊΠΎΠΏΠΈΠΈ, Π½ΠΎ Π½Π΅ Π² дСструкторС. ΠžΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄Π΅Π»Π°Ρ‚ΡŒ конструктор ΠΊΠΎΠΏΠΈΠΉ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния ΠΊΠΎΠΏΠΈΠΉ. ΠžΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅, ΠΏΠΎΡ‡Π΅ΠΌΡƒ класс Π½Π΅ нуТдаСтся Π² дСструкторС.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.26. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ класса StrBlob, описанного Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠΈ.

13.2.2. ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ классов, Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ

Π§Ρ‚ΠΎΠ±Ρ‹ класс HasPtr дСйствовал ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, конструктор ΠΊΠΎΠΏΠΈΠΉ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния ΠΊΠΎΠΏΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ-Ρ‡Π»Π΅Π½, Π° Π½Π΅ строку, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΠ½ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚. Класс всС Π΅Ρ‰Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π½ΡƒΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π² собствСнном дСструкторС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠΌ строку конструктором (см. Ρ€Π°Π·Π΄Π΅Π» 13.6). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС дСструктор Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ одностороннС ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΡΠ²ΡΠ·Π°Π½Π½ΡƒΡŽ с Π½ΠΈΠΌ строку. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° исчСзнСт послСдний ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° строку.

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ способ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ класс Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ β€” это ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ shared_ptr для управлСния рСсурсами Π² классС. ΠŸΡ€ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ (ΠΈΠ»ΠΈ присвоСнии) копируСтся (ΠΈΠ»ΠΈ присваиваСтся) ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ shared_ptr. Класс shared_ptr сам отслСТиваСт количСство ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚. Когда ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ большС Π½Π΅Ρ‚, класс shared_ptr освобоТдаСт рСсурс.

Но ΠΈΠ½ΠΎΠ³Π΄Π° ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ рСсурсом слСдуСт нСпосрСдствСнно. Π’ Ρ‚Π°ΠΊΠΈΡ… случаях ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ³ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ счСтчик ссылок (reference count) (см. Ρ€Π°Π·Π΄Π΅Π» 12.1.1). Для дСмонстрации Ρ€Π°Π±ΠΎΡ‚Ρ‹ счСтчика ссылок ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ класс HasPtr Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ, Π½ΠΎ с использованиСм собствСнного счСтчика ссылок.

Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊΠΈ ссылок

Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ ссылок Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

β€’ Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ конструктор (ΠΊΡ€ΠΎΠΌΠ΅ конструктора ΠΊΠΎΠΏΠΈΠΉ) создаСт счСтчик. Π­Ρ‚ΠΎΡ‚ счСтчик отслСТиваСт количСство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… создаваСмыС Π΄Π°Π½Π½Ρ‹Π΅. Π‘Ρ€Π°Π·Ρƒ послС создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½, поэтому счСтчик инициализируСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ 1.

β€’ ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΠΉ Π½Π΅ создаСт Π½ΠΎΠ²Ρ‹ΠΉ счСтчик; ΠΎΠ½ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π΅ΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ счСтчик. ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΠΉ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ счСтчика, указывая Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π΄Π°Π½Π½Ρ‹Ρ… этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

β€’ Π”Сструктор ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика, указывая, Ρ‡Ρ‚ΠΎ стало Π½Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… мСньшС. Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика достигаСт нуля, дСструктор удаляСт Π΄Π°Π½Π½Ρ‹Π΅.

β€’ ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния ΠΊΠΎΠΏΠΈΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ счСтчик ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ счСтчик Π»Π΅Π²ΠΎΠ³ΠΎ. Если счСтчик Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° достигаСт нуля, Π·Π½Π°Ρ‡ΠΈΡ‚, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ большС Π½Π΅Ρ‚. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния ΠΊΠΎΠΏΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π°.

ЕдинствСнноС Π·Π°Ρ‚Ρ€ΡƒΠ΄Π½Π΅Π½ΠΈΠ΅ β€” это Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Π³Π΄Π΅ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ счСтчик ссылок. Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‡Π»Π΅Π½ΠΎΠΌ нСпосрСдствСнно класса ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° HasPtr. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ ΠΏΠΎΡ‡Π΅ΠΌΡƒ, рассмотрим происходящСС Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

HasPtr p1("Hiya!");

HasPtr p2(p1); // p1 ΠΈ p2 ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° Ρ‚Ρƒ ΠΆΠ΅ строку

HasPtr p3(p1); // p1, p2 ΠΈ p3 ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° Ρ‚Ρƒ ΠΆΠ΅ строку

Если счСтчик ссылок Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅, Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈ создании ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° p3? МоТно ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ счСтчик Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ p1 ΠΈ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ счСт Π² p3, Π½ΠΎ ΠΊΠ°ΠΊ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ счСтчик Π² p2?

Один ΠΈΠ· способов Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ счСтчик Π² динамичСской памяти. ΠŸΡ€ΠΈ создании ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° рСзСрвируСтся Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ счСтчик. ΠŸΡ€ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΈΠ»ΠΈ присвоСнии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° копируСтся ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° счСтчик. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΈ копия, ΠΈ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» ΡƒΠΊΠ°ΠΆΡƒΡ‚ Π½Π° Ρ‚ΠΎΡ‚ ΠΆΠ΅ счСтчик.

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ класса счСтчика ссылок

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ счСтчик ссылок, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡƒΡŽ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ Π²Π΅Ρ€ΡΠΈΡŽ класса HasPtr ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

class HasPtr {

public:

 // конструктор Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ строку ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ счСтчик,

 // устанавливаСмый Π² 1

 HasPtr(const std::string &s = std::string()):

  ps(new std::string(s)), i(0), use(new std::size_t(1)) {}

 // конструктор ΠΊΠΎΠΏΠΈΠΉ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ всС Ρ‚Ρ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Π° ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚

 // счСтчик

 HasPtr(const HasPtr &p):

  ps(p.ps), i(p.i), use(p.use) { ++*use; }

 HasPtr& operator=(const HasPtr&);

 ~HasPtr();

private:

 std::string *ps;

 int i;

 std::size_t *use; // Ρ‡Π»Π΅Π½, ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ количСство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²,

                   // совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… *ps

};

Π—Π΄Π΅ΡΡŒ Π±Ρ‹Π»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° новая пСрСмСнная-Ρ‡Π»Π΅Π½ use, ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΡŽΡ‰Π°Ρ количСство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… Ρ‚Ρƒ ΠΆΠ΅ строку. ΠŸΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠΉ строку конструктор Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΠ΅Ρ‚ счСтчик ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ 1, ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ строкового Ρ‡Π»Π΅Π½Π° класса этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ копирования ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ класса ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ счСтчик ссылок

ΠŸΡ€ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΈΠ»ΠΈ присвоСнии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² класса HasPtr Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ копия ΠΈ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π»ΠΈ Π½Π° Ρ‚Ρƒ ΠΆΠ΅ строку. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° копируСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса HasPtr, копируСтся сам ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ps, Π° Π½Π΅ строка, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΠ½ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚. ΠŸΡ€ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ увСличиваСтся Ρ‚Π°ΠΊΠΆΠ΅ счСтчик, связанный с этой строкой.

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΠΉ (ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π² классС) ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ всС Ρ‚Ρ€ΠΈ Ρ‡Π»Π΅Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π΅ΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса HasPtr. Π­Ρ‚ΠΎΡ‚ конструктор ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ указатСля-Ρ‡Π»Π΅Π½Π° use, означая, Ρ‡Ρ‚ΠΎ Ρƒ строки, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ps ΠΈ p.ps, появился Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ.

ДСструктор Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Π΅Π·ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΎΡ‡Π½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ps, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Π½Π° Ρ‚Ρƒ ΠΆΠ΅ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ памяти. ВмСсто этого дСструктор осущСствляСт Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика ссылок, означая, Ρ‡Ρ‚ΠΎ строку совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π½Π° ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ мСньшС. Если счСтчик достигаСт нуля, дСструктор освобоТдаСт ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ps ΠΈ use:

HasPtr::~HasPtr() {

 if (--*use == 0) { // Ссли счСтчик ссылок достиг 0,

  delete ps;        // ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ строку

  delete use;       // ΠΈ счСтчик

 }

}

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

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ присвоСниС сСбя самому. Для этого ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика rhs осущСствляСтся ΠΏΡ€Π΅ΠΆΠ΄Π΅ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° счСтчика Π² Π»Π΅Π²ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π΅.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли ΠΎΠ±Π° ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‚Π΅ΠΌ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΎ ΠΏΡ€Π΅ΠΆΠ΄Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ нСобходимости удалСния ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ps ΠΈ use:

HasPtr& HasPtr::operator=(const HasPtr &rhs) {

 ++*rhs.use; // ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π°

 if (--*use == 0) { // Π·Π°Ρ‚Π΅ΠΌ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

  delete ps;        // Ссли Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π΅Ρ‚

  delete use;       // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

 }

 ps = rhs.ps;       // ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· rhs Π² этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

 i = rhs.i;

 use = rhs.use;

 return *this;      // Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

}

УпраТнСния Ρ€Π°Π·Π΄Π΅Π»Π° 13.2.2

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.27. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ класса HasPtr со счСтчиком ссылок.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.28. Π‘ ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… классов Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ стандартный конструктор ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ управлСния ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ.

(a) class TreeNode {    (b) class BinStrTree {

    private:                private:

     std::string value;      TreeNode *root;

     int count;             };

     TreeNode *left;

     TreeNode *right;

    };

13.3. Ѐункция swap()

ΠšΡ€ΠΎΠΌΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² управлСния ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ рСсурсами классы Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap() (см. Ρ€Π°Π·Π΄Π΅Π» 9.2.5). ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() особСнно Π²Π°ΠΆΠ½ΠΎ для классов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ планируСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ с Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°ΠΌΠΈ пСрСупорядочивания элСмСнтов (см. Ρ€Π°Π·Π΄Π΅Π» 10.2.3). Π’Π°ΠΊΠΈΠ΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap() всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΈΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΎΠ±ΠΌΠ΅Π½ Π΄Π²ΡƒΡ… элСмСнтов.