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

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

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

Если класс опрСдСляСт ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap(), Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Π΅. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ функция swap(), опрСдСлСнная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ. Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, Ρ…ΠΎΡ‚ΡŒ ΠΌΡ‹ ΠΏΠΎΠΊΠ° ΠΈ Π½Π΅ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ рСализуСтся функция swap(), ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ нСслоТно Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΠΌΠ΅Π½ Π΄Π²ΡƒΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² задСйствуСт ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ Π΄Π²Π° присвоСния. НапримСр, ΠΊΠΎΠ΄ ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π²ΡƒΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ класса HasPtr (см. Ρ€Π°Π·Π΄Π΅Π» 13.2.1) ΠΌΠΎΠ³ Π±Ρ‹ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

HasPtr temp = v1; // ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ копию значСния v1

v1 = v2;          // ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ v2 ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v1

v2 = temp;        // ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ сохранСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ v1 ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v2

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ Π΄Π²Π°ΠΆΠ΄Ρ‹ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ строку, которая ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Π»Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v1: ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° конструктор ΠΊΠΎΠΏΠΈΠΉ класса HasPtr ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ v1 Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ temp, ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния присваиваСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ temp ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v2. Он Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ строку, которая ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Π»Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v2, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ v2 присваиваСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ v1. Как ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ класса HasPtr, Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ строку ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ строку, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса HasPtr.

Π’ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ Π½ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· этих Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΉ памяти Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ. ВмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ ΠΊΠΎΠΏΠΈΠΈ строки, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΈΠΌΠ΅Π»ΠΎ Π±Ρ‹ смысл ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π²Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса HasPtr Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

string *temp = v1.ps; // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ копию указатСля Π² v1.ps

v1.ps = v2.ps;        // ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ v2.ps ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ v1.ps

v2.ps = temp;         // ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ сохранСнный ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ v1.ps

                      // ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ v2.ps

НаписаниС собствСнной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap()

ΠŸΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ стандартноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() ΠΌΠΎΠΆΠ½ΠΎ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ² Π² классС Π΅Π΅ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ. Π’ΠΎΡ‚ типичная рСализация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap():

class HasPtr {

 friend void swap(HasPtr&, HasPtr&);

 // Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹, ΠΊΠ°ΠΊ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 13.2.1

};

inline

void swap(HasPtr &lhs, HasPtr &rhs) {

 using std::swap;

 swap(lhs.ps, rhs.ps); // ΠΎΠ±ΠΌΠ΅Π½ указатСлями, Π° Π½Π΅ строковыми Π΄Π°Π½Π½Ρ‹ΠΌΠΈ

 swap(lhs.i, rhs.i);   // ΠΎΠ±ΠΌΠ΅Π½ цСлочислСнными Ρ‡Π»Π΅Π½Π°ΠΌΠΈ

}

ВсС начинаСтся с объявлСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), друТСствСнной, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΉ доступ ΠΊ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ-Ρ‡Π»Π΅Π½Π°ΠΌ класса HasPtr. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция swap() ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Π΅Π΅ ΠΊΠ°ΠΊ Π²ΡΡ‚Ρ€Π°ΠΈΠ²Π°Π΅ΠΌΡƒΡŽ (см. Ρ€Π°Π·Π΄Π΅Π» 6.5.2). Π’Π΅Π»ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…-Ρ‡Π»Π΅Π½ΠΎΠ² Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС сначала ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ цСлочислСнныС Ρ‡Π»Π΅Π½Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², связанных с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ rhs ΠΈ lhs.

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² управлСния ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, функция swap() Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ. Однако Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Π°ΠΆΠ½ΠΎ для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ классов, Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… рСсурсы.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), Π° Π½Π΅ std::swap()

Π’ этом ΠΊΠΎΠ΄Π΅ Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Π²Π°ΠΆΠ½Ρ‹ΠΉ нюанс: хотя Π² Π΄Π°Π½Π½ΠΎΠΌ случаС это Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ значСния, Π²Π°ΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ функция swap() Π²Ρ‹Π·Π²Π°Π»Π° ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap(), Π° Π½Π΅ std::swap(). Π’ классС HasPtr ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ встроСнныС Ρ‚ΠΈΠΏΡ‹. Для встроСнных Ρ‚ΠΈΠΏΠΎΠ² Π½Π΅Ρ‚ спСциализированных вСрсий Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(). Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΎΠ½Π° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ std::swap().

Но Ссли класс ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‡Π»Π΅Π½, Ρ‚ΠΈΠΏ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ собствСнной спСциализированной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ swap(), Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ std::swap() Π±Ρ‹Π» Π±Ρ‹ ошибкой. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ класс ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ Foo, пСрСмСнная-Ρ‡Π»Π΅Π½ h ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ HasPtr. Если Π½Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ для класса Foo ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ использована Π΅Π΅ библиотСчная вСрсия. Как ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, библиотСчная функция swap() осущСствляСт Π½Π΅Π½ΡƒΠΆΠ½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ строк, управляСмых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ класса HasPtr.

НСнуТного копирования ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ, написав Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap() для класса Foo. Но Π²Π΅Ρ€ΡΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() для класса Foo ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

void swap(Foo &lhs, Foo &rhs) {

 // Ошибка: эта функция ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ

 // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), Π° Π½Π΅ Π²Π΅Ρ€ΡΠΈΡŽ класса HasPtr

 std::swap(lhs.h, rhs.h); // ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ класса Foo

}

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ компилируСтся ΠΈ выполняСтся. Однако Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ различия Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ этим ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΌ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ здСсь явно Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ Π²Ρ‹Π·ΠΎΠ² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΠΎΠΉ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(). Однако Π½ΡƒΠΆΠ½Π° вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ ΠΈΠ· пространства ΠΈΠΌΠ΅Π½ std, Π° опрСдСлСнная Π² классС HasPtr.

ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ способ написания Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π½ΠΈΠΆΠ΅.

void swap(Foo &lhs, Foo &rhs) {

 using std::swap;

 swap(lhs.h, rhs.h); // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap() класса HasPtr

 // ΠΎΠ±ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ класса Foo

}

ВсС Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() обходятся Π±Π΅Π· ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ². Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΊΠ°ΠΊ swap(), Π° Π½Π΅ std::swap(). По ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ, рассматриваСмым Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 16.3, Ссли Π΅ΡΡ‚ΡŒ спСцифичСская для Ρ‚ΠΈΠΏΠ° вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), ΠΎΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π»ΡƒΡ‡ΡˆΠΈΠΌ соотвСтствиСм, Ρ‡Π΅ΠΌ таковая ΠΈΠ· пространства ΠΈΠΌΠ΅Π½ std. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅, Ссли Ρƒ Ρ‚ΠΈΠΏΠ° Π΅ΡΡ‚ΡŒ спСцифичСская вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap(), Π²Ρ‹Π·ΠΎΠ² swap() Π±ΡƒΠ΄Π΅Ρ‚ распознан ΠΊΠ°ΠΊ относящийся ΠΊ спСцифичСской вСрсии. Если спСцифичСской для Ρ‚ΠΈΠΏΠ° вСрсии Π½Π΅Ρ‚, Ρ‚ΠΎ (с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ объявлСния using для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π² области видимости) ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ swap() Π±ΡƒΠ΄Π΅Ρ‚ использована вСрсия ΠΈΠ· пространства ΠΈΠΌΠ΅Π½ std.

Π£ ΠΎΡ‡Π΅Π½ΡŒ остороТных Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ вопрос: ΠΏΠΎΡ‡Π΅ΠΌΡƒ объявлСниС using Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π½Π΅ скрываСт объявлСниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() класса HasPtr (см. Ρ€Π°Π·Π΄Π΅Π» 6.4.1). ΠŸΡ€ΠΈΡ‡ΠΈΠ½Ρ‹, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ этот ΠΊΠΎΠ΄, ΠΎΠ±ΡŠΡΡΠ½ΡΡŽΡ‚ΡΡ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 18.2.3.

ИспользованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ… присвоСния

ΠšΠ»Π°ΡΡΡ‹, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ swap(), Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π΅Π΅ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ собствСнного ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присвоСния. Π­Ρ‚ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡŽ, ΠΈΠ·Π²Π΅ΡΡ‚Π½ΡƒΡŽ ΠΊΠ°ΠΊ копия ΠΈ ΠΎΠ±ΠΌΠ΅Π½ (copy and swap)). Она ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ ΠΎΠ±ΠΌΠ΅Π½ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° с ΠΊΠΎΠΏΠΈΠ΅ΠΉ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ:

// ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ rhs пСрСдаСтся ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚,

// Ρ‡Ρ‚ΠΎ конструктор ΠΊΠΎΠΏΠΈΠΉ класса HasPtr ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ строку Π² ΠΏΡ€Π°Π²Ρ‹ΠΉ

// ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ rhs

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

 // ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Π΅Ρ‚ содСрТимоС Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° с локальной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ rhs

 swap(*this, rhs); // Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ rhs ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΠΏΠ°ΠΌΡΡ‚ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ

                   // использовал этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

 return *this; // ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ rhs ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΡŽ указатСля Π² rhs

}

Π’ этой вСрсии ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присвоСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ являСтся ссылкой. ВмСсто этого ΠΏΡ€Π°Π²Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ пСрСдаСтся ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, rhs β€” это копия ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π°. ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса HasPtr ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π½ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ строки Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Π’ Ρ‚Π΅Π»Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присвоСния вызываСтся функция swap(), ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°ΡŽΡ‰Π°Ρ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ rhs с Ρ‚Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ Π² *this. Π­Ρ‚ΠΎΡ‚ Π²Ρ‹Π·ΠΎΠ² ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» Π² Π»Π΅Π²ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π΅, Π² rhs, ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» Π² rhs,β€” Π² *this. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, послС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ swap() ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ-Ρ‡Π»Π΅Π½ Π² *this ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π½Π΅Π΄Π°Π²Π½ΠΎ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ строку, ΡΠ²Π»ΡΡŽΡ‰ΡƒΡŽΡΡ ΠΊΠΎΠΏΠΈΠ΅ΠΉ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π°.

По Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присвоСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ rhs удаляСтся ΠΈ выполняСтся дСструктор класса HasPtr. Π­Ρ‚ΠΎΡ‚ дСструктор освобоТдаСт ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ rhs, освобоТдая Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π» Π»Π΅Π²Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄.

Π’ этой Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ интСрСсСн Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° автоматичСски ΠΎΡ‚Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ присвоСниС сСбя сСбС ΠΈ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ устойчива ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌ. ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° Π΄ΠΎ измСнСния Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΡ‚Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ присвоСниС сСбя сСбС Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½Π½ΠΎΠΌΡƒ Π² нашСм ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ присвоСния (см. Ρ€Π°Π·Π΄Π΅Π» 13.2.1). Π­Ρ‚ΠΎ обСспСчиваСт ΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌ Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈ Π² ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ. ЕдинствСнный ΠΊΠΎΠ΄, способный ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, β€” это ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ new Π² конструкторС ΠΊΠΎΠΏΠΈΠΉ. Если ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, Ρ‚ΠΎ это случится ΠΏΡ€Π΅ΠΆΠ΄Π΅, Ρ‡Π΅ΠΌ измСнится Π»Π΅Π²Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ присвоСния, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ копию ΠΈ ΠΎΠ±ΠΌΠ΅Π½, автоматичСски устойчивы ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌ ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΡ‚Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ присвоСниС сСбя сСбС.