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

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

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

β€’ ΠšΠΎΠ΄ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ дСскрипторы, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ вашим классом, ΠΈ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ вашСго класса сдСлаСт ΠΈΡ… Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ.

РаспространСнная ошибка Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ дСйствиС const Π½Π° самом Π΄Π΅Π»Π΅ Π½Π΅Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΈ Π½Π΅ распространяСтся посрСдством ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 15). НапримСр, Socket::GetHandle β€” константный Ρ‡Π»Π΅Π½; ΠΏΠΎΠΊΠ° ΠΌΡ‹ рассматриваСм ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния компилятора, Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ handlΠ΅_ сохраняСт ΠΊΠΎΠ½ΡΡ‚Π°Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Однако нСпосрСдствСнный Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы с использованиСм значСния handlΠ΅_ Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ косвСнно обращаСтся handlΠ΅_.

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π΄Π°Π»Π΅Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΡ‡Π΅Π½ΡŒ прост, хотя Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ситуация нСсколько Π»ΡƒΡ‡ΡˆΠ΅ β€” ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ случайного Π½Π΅Π²Π΅Ρ€Π½ΠΎΠ³ΠΎ употрСблСния Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния, описав Π΅Π³ΠΎ Ρ‚ΠΈΠΏ ΠΊΠ°ΠΊ const:

class String {

 char* buffer_;

public:

 char* GetBuffer() const { return buffer_; }

 // ΠŸΠ»ΠΎΡ…ΠΎ: слСдуСт Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ const char*


 // ...

};

Π₯отя функция GetBuffer константная, тСхничСски этот ΠΊΠΎΠ΄ Π²ΠΏΠΎΠ»Π½Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π΅Π½. ΠŸΠΎΠ½ΡΡ‚Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ GetBuffer для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ String мноТСством Ρ€Π°Π·Π½Ρ‹Ρ… способов, Π½Π΅ прибСгая ΠΊ явному ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΡŽ Ρ‚ΠΈΠΏΠΎΠ². НапримСр, strcpy(s.GetBuffer(), "Very Long String...") β€” Π²ΠΏΠΎΠ»Π½Π΅ Π·Π°ΠΊΠΎΠ½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄; любой компилятор пропустит Π΅Π³ΠΎ Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ… Π±Ρ‹ Ρ‚ΠΎ Π½ΠΈ Π±Ρ‹Π»ΠΎ Π·Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠΉ. Если Π±Ρ‹ ΠΌΡ‹ объявили Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ‚ΠΈΠΏ ΠΊΠ°ΠΊ const char*, Ρ‚ΠΎ прСдставлСнный ΠΊΠΎΠ΄ Π²Ρ‹Π·Π²Π°Π» Π±Ρ‹, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, ΠΎΡˆΠΈΠ±ΠΊΡƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ компиляции, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ случайно ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΡΡ‚ΠΎΠ»ΡŒ опасно Π±Ρ‹Π»ΠΎ Π±Ρ‹ просто Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ β€” Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ явноС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ 92 ΠΈ 95).

Но Π΄Π°ΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° const Π½Π΅ устраняСт возмоТности случайного Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ использования, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ имССтся Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, связанная с ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒΡŽ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… класса. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ с классом String, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ GetBuffer, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄ΡƒΡ‚ ΠΊ росту (ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΡŽ) Π±ΡƒΡ„Π΅Ρ€Π° String, Ρ‡Ρ‚ΠΎ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ использованию сохранСнного, Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ указатСля Π½Π° Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π±ΡƒΡ„Π΅Ρ€. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли Π²Ρ‹ считаСтС, Ρ‡Ρ‚ΠΎ Ρƒ вас Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ для обСспСчСния Ρ‚Π°ΠΊΠΎΠ³ΠΎ доступа ΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ, Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Π΄ΠΎΠ»Π³ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ остаСтся ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π΄Π΅Π»Π°ΡŽΡ‚ Π΅Π³ΠΎ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ (сравнитС с гарантиями коррСктности явных ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ; см. [C++03]).

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

Иногда классы обязаны ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ доступ ΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌ дСскрипторам ΠΏΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ, связанным с ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для интСрфСйса со старым ΠΊΠΎΠ΄ΠΎΠΌ ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ использовании Π΄Ρ€ΡƒΠ³ΠΈΡ… систСм. НапримСр, std::basic_string прСдоставляСт доступ ΠΊ своСму Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ дСскриптору посрСдством Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² data ΠΈ c_str для совмСстимости с функциями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с указатСлями Π‘ β€” Π½ΠΎ Π½Π΅ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ эти ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΈ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ запись с ΠΈΡ… ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ! Π’Π°ΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ доступа "Ρ‡Π΅Ρ€Π΅Π· заднюю Π΄Π²Π΅Ρ€ΡŒ" всСгда ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π·Π»ΠΎΠΌ ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΡ‡Π΅Π½ΡŒ Ρ€Π΅Π΄ΠΊΠΎ ΠΈ ΠΎΡ‡Π΅Π½ΡŒ остороТно, Π° условия коррСктности Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Ρ… ΠΈΠΌΠΈ дСскрипторов Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΡ‡Π½ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.

Бсылки

[Π‘++03] Β§23 β€’ [Dewhurst03] Β§80 β€’ [Meyers97] #29 β€’ [Saks99] β€’ [Stroustrup00] Β§7.3 β€’ [Sutter02] Β§9

43. Π Π°Π·ΡƒΠΌΠ½ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΈΠ΄ΠΈΠΎΠΌΠΎΠΉ Pimpl

РСзюмС

Π‘++ Π΄Π΅Π»Π°Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ нСдоступными, Π½ΠΎ Π½Π΅ Π½Π΅Π²ΠΈΠ΄ΠΈΠΌΡ‹ΠΌΠΈ. Π’Π°ΠΌ, Π³Π΄Π΅ это оправдываСтся ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΡ‹ΠΌΠΈ прСимущСствами, слСдуСт ΠΏΠΎΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎΠ± истинной нСвидимости, достигаСмой ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΈΠ΄ΠΈΠΎΠΌΡ‹ Pimpl (указатСля Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ) для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ брандмауэров компилятора ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ сокрытия ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ 11 ΠΈ 41).

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

Когда ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ "брандмауэр компилятора", ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΎΡ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… частСй класса, Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΈΠ΄ΠΈΠΎΠΌΠΎΠΉ Pimpl (указатСля Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ): скройтС ΠΈΡ… Π·Π° Π½Π΅ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ (ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ (ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ подходящий ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ) Π½Π° ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ, Π½ΠΎ ΠΏΠΎΠΊΠ° Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ класс). НапримСр:

class Map {

 // ...

private:

 struct Impl;

 shared_ptr<Impl> pimpl_;

};

Π”Π°ΡŽΡ‰ΠΈΠΉ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΈΠ΄ΠΈΠΎΠΌΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для хранСния всСх Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ‡Π»Π΅Π½ΠΎΠ², ΠΊΠ°ΠΊ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊ ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ². Π­Ρ‚ΠΎ позволяСт Π²Π°ΠΌ Π²Π½ΠΎΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ измСнСния Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Π΄Π΅Ρ‚Π°Π»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²Π°ΡˆΠΈΡ… классов Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠΉ Π±Ρ‹ Ρ‚ΠΎ Π½ΠΈ Π±Ρ‹Π»ΠΎ рСкомпиляции Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π°. Π‘Π²ΠΎΠ±ΠΎΠ΄Π° ΠΈ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ β€” Π²ΠΎΡ‚ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‡Π΅Ρ€Ρ‚Ρ‹ рассматриваСмой ΠΈΠ΄ΠΈΠΎΠΌΡ‹ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 41).

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: ΠΎΠ±ΡŠΡΠ²Π»ΡΠΉΡ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ β€” с использованиСм Π΄Π²ΡƒΡ… объявлСний. Если Π²Ρ‹ скомбинируСтС Π΄Π²Π΅ строки с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ объявлСниСм Ρ‚ΠΈΠΏΠ° ΠΈ указатСля Π½Π° Π½Π΅Π³ΠΎ Π² ΠΎΠ΄Π½Ρƒ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ struct Impl *pimpl; это Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΏΠΎΠ»Π½Π΅ Π·Π°ΠΊΠΎΠ½Π½ΠΎ, Π½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ смысл объявлСния: Π² этом случаС Impl находится Π² ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌ пространствС ΠΈΠΌΠ΅Π½ ΠΈ Π½Π΅ являСтся Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ вашСго класса.

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ Ρ‚Ρ€ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ для использования Pimpl, ΠΈ всС ΠΎΠ½ΠΈ Π²Ρ‹Ρ‚Π΅ΠΊΠ°ΡŽΡ‚ ΠΈΠ· различия ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒΡŽ (Π² состоянии Π»ΠΈ Π²Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚) ΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ (Π²ΠΈΠ΄ΠΈΠΌ Π»ΠΈ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ для вас ΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, зависитС Π»ΠΈ Π²Ρ‹ ΠΎΡ‚ Π΅Π³ΠΎ опрСдСлСния) Π² Π‘++. Π’ частности, всС Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ класса нСдоступны Π½ΠΈΠΊΠΎΠΌΡƒ, ΠΊΡ€ΠΎΠΌΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ- Ρ‡Π»Π΅Π½ΠΎΠ² ΠΈ Π΄Ρ€ΡƒΠ·Π΅ΠΉ, Π½ΠΎ Π·Π°Ρ‚ΠΎ Π²ΠΈΠ΄ΠΈΠΌΡ‹ всСм β€” Π»ΡŽΠ±ΠΎΠΌΡƒ ΠΊΠΎΠ΄Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π²ΠΈΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ класса.

ΠŸΠ΅Ρ€Π²ΠΎΠ΅ слСдствиС этого β€” ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ большСС врСмя сборки прилоТСния ΠΈΠ·-Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈΠ·Π»ΠΈΡˆΠ½ΠΈΡ… ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠΎΠ². Для Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…-Ρ‡Π»Π΅Π½ΠΎΠ², хранящихся ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ², ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π² Π²ΠΈΠ΄ΠΈΠΌΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚ΠΈΠΏΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π² Π΄Π°Π½Π½ΠΎΠΉ Π΅Π΄ΠΈΠ½ΠΈΡ†Π΅ компиляции. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΡŽ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ сборки, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

class C {

 // ...

private:

 AComplicatedType act_;

}

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», содСрТащий ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ класса Π‘, Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», содСрТащий ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ AComplicatedType, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Ρ‚Ρ€Π°Π½Π·ΠΈΡ‚ΠΈΠ²Π½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ всС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ для опрСдСлСния AComplicatedType, ΠΈ Ρ‚.Π΄. Если Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ большиС Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹, врСмя компиляции ΠΌΠΎΠΆΠ΅Ρ‚ сущСствСнно ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒΡΡ.

Π’Ρ‚ΠΎΡ€ΠΎΠ΅ слСдствиС β€” созданиС нСоднозначностСй ΠΈ сокрытиС ΠΈΠΌΠ΅Π½ для ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пытаСтся Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. НСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ закрытая функция-Ρ‡Π»Π΅Π½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π½Π° ΠΊΠΎΠ΄ΠΎΠΌ Π²Π½Π΅ Π΅Π΅ класса ΠΈ Π΅Π³ΠΎ Π΄Ρ€ΡƒΠ·Π΅ΠΉ, ΠΎΠ½Π° Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ участвуСт Π² поискС ΠΈΠΌΠ΅Π½ ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈ Ρ‚Π΅ΠΌ самым ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ. ΠŸΠ΅Ρ€Π΅Π΄ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ доступности Π‘++ выполняСт поиск ΠΈΠΌΠ΅Π½ ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ. Из-Π·Π° этого Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΈΠΌΠ΅Π΅Ρ‚ Π±ΠΎΠ»Π΅Π΅ высокий ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚:

int Twice(int);        // 1


class Calc {

public:

 string Twice(string); // 2


private:

 char* Twice(char*);   // 3


 int Test() {

  return Twice(21);   // A: ошибка, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ 2 ΠΈ 3 Π½Π΅

   // подходят (ΠΌΠΎΠ³Π»Π° Π±Ρ‹ ΠΏΠΎΠ΄ΠΎΠΉΡ‚ΠΈ функция 1, Π½ΠΎ

   // Π΅Π΅ нСльзя Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΠΎΠ½Π° скрыта ΠΎΡ‚

   // Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°)

 }

};


Calc с;

с.Twice("Hello");     // Π‘: ошибка, функция 3

 // нСдоступна (ΠΌΠΎΠ³Π»Π° Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ

 // функция 2, Π½ΠΎ ΠΎΠ½Π° Π½Π΅ рассматриваСтся, Ρ‚Π°ΠΊ

 // ΠΊΠ°ΠΊ Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ 3 Π»ΡƒΡ‡ΡˆΠ΅Π΅ соотвСтствиС

 // Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρƒ)

Π’ строкС А ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ явно ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² ΠΊΠ°ΠΊ ::Twice(21) для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ поиск ΠΈΠΌΠ΅Π½ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π’ строкС Π‘ ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ состоит Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ явного прСобразования Ρ‚ΠΈΠΏΠ° с.TwiсС(string("HellΠΎ")) для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. НСкоторыС ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, связанных с Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ, ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΈ Π±Π΅Π· примСнСния ΠΈΠ΄ΠΈΠΎΠΌΡ‹ Pimpl, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ², Π½ΠΎ Π½Π΅ для всСх ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌΡ‹Ρ… ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΈΠ΄ΠΈΠΎΠΌΡ‹ Pimpl, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Ρ‚Π°ΠΊΠΈΠ΅ ΠΎΠ±Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ.

Π’Ρ€Π΅Ρ‚ΡŒΠ΅ слСдствиС влияСт Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ошибок ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Widget Π’ΠΎΠΌΠ° ΠšΠ°Ρ€Π³ΠΈΠ»Π»Π° (Tom Cargill):

class Widget { // ...

public:

 Widget& operator=(const Widget&);

private:

 T1 t1_;

 T2 t2_;

};

ΠšΠΎΡ€ΠΎΡ‚ΠΊΠΎ говоря, ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ operator=, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обСспСчиваСт ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡŽ (ΠΈΠ»ΠΈ хотя Π±Ρ‹ Π±Π°Π·ΠΎΠ²ΡƒΡŽ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡŽ), Ссли ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ T1 ΠΈΠ»ΠΈ T2 ΠΌΠΎΠ³ΡƒΡ‚ Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π΅ΠΎΠ±Ρ€Π°Ρ‚ΠΈΠΌΡ‹Π΅ сбои (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 71). Π₯ΠΎΡ€ΠΎΡˆΠΈΠ΅ новости, ΠΎΠ΄Π½Π°ΠΊΠΎ, состоят Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ привСдСнная Π΄Π°Π»Π΅Π΅ простая трансформация всСгда обСспСчиваСт, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, Π±Π°Π·ΠΎΠ²ΡƒΡŽ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡŽ для бСзопасного присваивания, ΠΈ ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ β€” ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡŽ, Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ T1 ΠΈ T2 (Π° ΠΈΠΌΠ΅Π½Π½ΠΎ β€” конструкторы ΠΈ дСструкторы) Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов. Для этого слСдуСт Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π΅ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π° посрСдством ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ спрятанными Π·Π° СдинствСнным ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ: