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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ программирования Π½Π° Π‘++. 101 ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ ΠΈ рСкомСндация». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 29

Автор Π“Π΅Ρ€Π± Π‘Π°Ρ‚Ρ‚Π΅Ρ€

[C++03] Β§15.2(3), Β§17.4.4.8(3) β€’ [Meyers96] Β§11 β€’ [Stroustrup00] Β§14.4.7, Β§E.2-4 β€’ [Sutter00] Β§8, Β§16 β€’ [Sutter02] Β§18-19

52. ΠšΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΈ Π»ΠΈΠΊΠ²ΠΈΠ΄ΠΈΡ€ΡƒΠΉΡ‚Π΅ согласованно

РСзюмС

Если Π²Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ ΠΎΠ΄Π½Ρƒ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ списка Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ β€” ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ присваивания ΠΈΠ»ΠΈ дСструктор β€” вСроятно, Π²Π°ΠΌ потрСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΈ ΠΎΠ±Π΅ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (ΠΈΠ»ΠΈ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΎΠ΄Π½Ρƒ ΠΈΠ· Π½ΠΈΡ…).

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

Если Π²Π°ΠΌ трСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈΠ· Ρ‚Ρ€Π΅Ρ… пСрСчислСнный Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ трСбуСтся Π½Π΅Ρ‡Ρ‚ΠΎ большСС, Ρ‡Π΅ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π° всС эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ асиммСтрично взаимосвязаны.

β€’ Π•сли Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΈΠ»ΠΈ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор ΠΈΠ»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ присваивания, Ρ‚ΠΎ, вСроятно, Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС ΠΈ для Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· этой ΠΏΠ°Ρ€Ρ‹. Если ΠΎΠ΄Π½Π° функция выполняСт Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ "ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ" Ρ€Π°Π±ΠΎΡ‚Ρƒ, вСроятно, другая Π΄ΠΎΠ»ΠΆΠ½Π° Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠ΅, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ эти Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ дСйствиС (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 53, которая поясняСт этот ΠΏΡƒΠ½ΠΊΡ‚).

β€’ Π•сли Π²Ρ‹ явно ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, вСроятно, Π²Π°ΠΌ Π½Π°Π΄ΠΎ явно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈ дСструктор. Если "ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ" Ρ€Π°Π±ΠΎΡ‚Π° Π² ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ конструкторС Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΈΠ»ΠΈ Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рСсурса (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, памяти, Ρ„Π°ΠΉΠ»Π°, сокСта), Ρ‚ΠΎ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ этот рСсурс Π² дСструкторС.

β€’ Π•сли Π²Ρ‹ явно ΠΏΠΈΡˆΠ΅Ρ‚Π΅ дСструктор, вСроятно, Π²Π°ΠΌ трСбуСтся явно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ (ΠΈΠ»ΠΈ явно Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚ΡŒ) ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Если Π²Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ Π½Π΅Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ дСструктор, это Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ трСбуСтся Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ рСсурс, хранящийся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ. Если Ρ‚Π°ΠΊ, вСроятно, для этого рСсурса трСбуСтся Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎΠ΅ Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ слСдуСт ΡƒΠ΄Π΅Π»ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ способу копирования ΠΈ присваивания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ²ΠΎΠ΅.

Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ инкапсулированного рСсурса с использованиСм ΠΈΠ΄ΠΈΠΎΠΌΡ‹ RAII позволяСт ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 13).

ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹, сгСнСрированныС компилятором. Волько ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ "Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅", ΠΈ ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ ΠΎΠ΄ΠΈΠ½ ΠΊΡ€ΡƒΠΏΠ½Ρ‹ΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ STL ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ для классов с Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями. ΠŸΠΎΡ…ΠΎΠΆΠ΅, вскорС это станСт распространСнным явлСниСм.

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

Когда любая ΠΈΠ· ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ объявлСна Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΉ ΠΈΠ»ΠΈ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ, Π½ΠΎ Π±Π΅Π· ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ сСмантики, это Π½Π΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ нСобходимости наличия ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

Π’ Ρ€Π΅Π΄ΠΊΠΈΡ… случаях классы, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ странных Ρ‚ΠΈΠΏΠΎΠ² (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ссылки, std::auto_ptr), ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ сСмантику копирования. Π’ классС, хранящСм ссылку ΠΈΠ»ΠΈ auto_ptr, Π²Π°ΠΌ, вСроятно, потрСбуСтся Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания, Π½ΠΎ дСструктор ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ. (Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ использованиС Ρ‡Π»Π΅Π½Π°, ΡΠ²Π»ΡΡŽΡ‰Π΅Π³ΠΎΡΡ ссылкой ΠΈΠ»ΠΈ auto_ptr, ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ).

Бсылки

[Cline99] Β§30.01-14 β€’ [Koenig97] Β§4 β€’ [Stroustrup00] Β§5.5, Β§10.4 β€’ [SuttHysl04b]

53. Π―Π²Π½ΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΠΉΡ‚Π΅ ΠΈΠ»ΠΈ Π·Π°ΠΏΡ€Π΅Ρ‰Π°ΠΉΡ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

РСзюмС

ΠšΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ со Π·Π½Π°Π½ΠΈΠ΅ΠΌ Π΄Π΅Π»Π°: Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹Π±ΠΈΡ€Π°ΠΉΡ‚Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ использованиСм сгСнСрированных компилятором ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ конструктора ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° присваивания, написаниСм собствСнных вСрсий ΠΈΠ»ΠΈ явным Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΠΎΠΈΡ…, Ссли ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΎ.

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

РаспространСнной ошибкой (ΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ срСди Π½ΠΎΠ²ΠΈΡ‡ΠΊΠΎΠ²) являСтся ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ сСмантики копирования ΠΈ присваивания ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ класса. Π­Ρ‚ΠΎ Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½ΠΎ для ΠΌΠ°Π»Π΅Π½ΡŒΠΊΠΈΡ… Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… классов, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Π΅ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈΠ΄ΠΈΠΎΠΌΡ‹ RAII (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 13).

Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ваш класс прСдоставляСт осмыслСнноС ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (ΠΈΠ»ΠΈ Π½Π΅ прСдоставляСт Π΅Π³ΠΎ вовсС). Π’ΠΎΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹.

β€’ Π―Π²Π½ΠΎΠ΅ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ±Π΅ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Если ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для вашСго Ρ‚ΠΈΠΏΠ° лишСно смысла, Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚Π΅ ΠΊΠ°ΠΊ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ конструированиС, Ρ‚Π°ΠΊ ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ присваиваниС, объявив ΠΈΡ… ΠΊΠ°ΠΊ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Π½Π΅Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

class T { // ...

private:                 // Π”Π΅Π»Π°Π΅ΠΌ T Π½Π΅ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌ

 T(const T&);            // Ѐункция Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π°

 T& operator=(const T&); // Ѐункция Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π°

};

β€’ Π―Π²Π½ΠΎΠ΅ написаниС ΠΎΠ±Π΅ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Если для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² T прСдусмотрСны ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ присваиваниС, Π½ΠΎ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ отличаСтся ΠΎΡ‚ повСдСния сгСнСрированных компилятором вСрсий, Ρ‚ΠΎ слСдуСт явно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠ±Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΡ… Π½Π΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌΠΈ.

β€’ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ сгСнСрированных компилятором вСрсий, ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ с явным ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅ΠΌ. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС, Ссли ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ компилятору самому ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ…. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ явно ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ повСдСния ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ вашСго ΠΊΠΎΠ΄Π° Π·Π½Π°Π»ΠΈ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΏΡ€Π΅Π΄Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎ Π½Π΅ объявили Π΄Π°Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΈΠ΅ копирования ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ присваивания ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ T Π² стандартныС ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹. Π­Ρ‚ΠΎ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ»ΠΎΡ…ΠΎ; ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π² любом случаС Π½Π΅ Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°Ρ…. (Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π²Ρ‹ всС Ρ€Π°Π²Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ эти ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Ссли Π±ΡƒΠ΄Π΅Ρ‚Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΡ… посрСдством ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ; см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 79).

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

Бсылки

[Dewhurst03] Β§88 β€’ [Meyers97] Β§11 β€’ [Stroustrup00] Β§11.2.2

54. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ срСзки. ΠŸΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ ΠΎΠ± использовании Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС клонирования вмСсто копирования

РСзюмС

Π‘Ρ€Π΅Π·ΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² происходит автоматичСски, Π½Π΅Π²ΠΈΠ΄ΠΈΠΌΠΎ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊ ΠΏΠΎΠ»Π½ΠΎΠΌΡƒ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΡŽ чудСсного ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎΠ³ΠΎ Π΄ΠΈΠ·Π°ΠΉΠ½Π°. ΠŸΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ ΠΎ ΠΏΠΎΠ»Π½ΠΎΠΌ Π·Π°ΠΏΡ€Π΅Ρ‚Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ конструктора ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ присваивания Π² Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классах. ВмСсто Π½ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ Clone, Ссли ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ вашСго класса Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½Ρ‹Π΅ (ΠΏΠΎΠ»Π½Ρ‹Π΅, Π³Π»ΡƒΠ±ΠΎΠΊΠΈΠ΅) ΠΊΠΎΠΏΠΈΠΈ.

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

Когда Π²Ρ‹ строитС ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ классов, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ½Π° ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для получСния ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎΠ³ΠΎ повСдСния. Π’Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π±ΡƒΠ΄ΡƒΡ‡ΠΈ созданными, сохраняли свой Ρ‚ΠΈΠΏ ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΎΡΡ‚ΡŒ. Π­Ρ‚Π° Ρ†Π΅Π»ΡŒ вступаСт Π² ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ с ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ сСмантикой копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² C++, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор Π½Π΅ являСтся Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлан Ρ‚Π°ΠΊΠΎΠ²Ρ‹ΠΌ. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

class B { /* ... */ };


class D : public B { /* ... */ };


// Оп! ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ

void Transmogrify(B obj);


void Transubstantiate(B& obj) { // ВсС Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ -

                                // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΏΠΎ ссылкС

 Transmogrify(obj);             // ΠŸΠ»ΠΎΡ…ΠΎ! Π‘Ρ€Π΅Π·ΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°!

 // ...

}


D d;

Transubstantiate(d);

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡΡ‚ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π’ ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… классов ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎ. Однако, ΠΏΠΎ ошибкС (ΠΈΠ»ΠΈ усталости β€” ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΈ ΠΊΠΎΡ„Π΅ закончился…) программист ΠΈΠ»ΠΈ просто Π·Π°Π±Ρ‹Π» Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ & Π² сигнатурС Transmogrify, ΠΈΠ»ΠΈ собирался ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ копию, Π½ΠΎ сдСлал это Π½Π΅Π²Π΅Ρ€Π½ΠΎ. Код компилируСтся Π±Π΅Π· ошибок, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° функция Transmogrify вызываСтся с ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ΠΉ Π΅ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° D, ΠΎΠ½ ΠΌΡƒΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ B. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Ρ‹Π·ΠΎΠ²Ρƒ B::Π’(const B&), Ρ‚.Π΅. ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ конструктора Π’, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ const B& прСдставляСт собой автоматичСски ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½Π½ΡƒΡŽ ссылку Π½Π° d. Π§Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΏΠΎΡ‚Π΅Ρ€Π΅ динамичСского, ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎΠ³ΠΎ повСдСния, ΠΈΠ·-Π·Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ наслСдованиС.

Если, ΠΊΠ°ΠΊ Π°Π²Ρ‚ΠΎΡ€ класса Π’, Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ срСзку, Π½ΠΎ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° ΠΌΠΎΠ³Π»Π° ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΠΎ ошибкС, для Ρ‚Π°ΠΊΠΎΠ³ΠΎ случая сущСствуСт ΠΎΠ΄ΠΈΠ½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ дСйствий, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΡ‹ упомянСм для ΠΏΠΎΠ»Π½ΠΎΡ‚Ρ‹ излоТСния, Π½ΠΎ Π½Π΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² ΠΊΠΎΠ΄Π΅, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΏΡ€Π΅Π΄ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠ΅ пСрСносимости: Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор Π’ ΠΊΠ°ΠΊ explicit. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ нСявной срСзки, Π½ΠΎ ΠΊΡ€ΠΎΠΌΠ΅ этого Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ всС ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ (Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π²ΠΏΠΎΠ»Π½Π΅ ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ‹ΠΌ для Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классов, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… всС Ρ€Π°Π²Π½ΠΎ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒΡΡ; см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 35).

// ОбъявляСм ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор ΠΊΠ°ΠΊ explicit (Ρƒ Π΄Π°Π½Π½ΠΎΠ³ΠΎ

// Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ имССтся ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠ΅ дСйствиС, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ трСбуСтся

// ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°)

class B { // ...

public: