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

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

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

β€’ Π’ΠΈΠΏ int Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 16 Π±ΠΈΡ‚ΠΎΠ².

Π’ частности, достаточно распространСнныС соглашСния Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π½ΠΈ для всСх ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€, Π½ΠΈ Ρ‚Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅ для Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡΠ²ΠΈΡ‚ΡŒΡΡ Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ.

β€’ Π Π°Π·ΠΌΠ΅Ρ€ int Π½Π΅ Ρ€Π°Π²Π΅Π½ Π½ΠΈ 32 Π±ΠΈΡ‚Π°ΠΌ, Π½ΠΈ ΠΊΠ°ΠΊΠΎΠΌΡƒ-Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΎΠΌΡƒ фиксированному Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ.

β€’ Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΈ Ρ†Π΅Π»Ρ‹Π΅ числа Π½Π΅ всСгда ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ свободно ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒΡΡ Π΄Ρ€ΡƒΠ³ Π² Π΄Ρ€ΡƒΠ³Π°.

β€’ Π Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ класса Π² памяти Π½Π΅ всСгда ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΡŽ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса ΠΈ Ρ‡Π»Π΅Π½ΠΎΠ² Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ порядкС.

β€’ ΠœΠ΅ΠΆΠ΄Ρƒ Ρ‡Π»Π΅Π½Π°ΠΌΠΈ класса (Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ POD) ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠΈ Π² цСлях выравнивания.

β€’ offsetof Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для POD, Π½ΠΎ Π½Π΅ для всСх классов (хотя компилятор ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈ Π½Π΅ ΡΠΎΠΎΠ±Ρ‰Π°Ρ‚ΡŒ ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…).

β€’ ΠšΠ»Π°ΡΡ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ скрытыС поля.

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

β€’ ΠΠ΅Π»ΡŒΠ·Ρ пСрСносимо ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ автоматичСских ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π² памяти ΠΈΠ»ΠΈ Π½Π° Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ роста стСка.

β€’ Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€, ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° указатСля void*, нСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ API Π·Π°ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ вас ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΡ… Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹.

β€’ Π˜Π·-Π·Π° вопросов выравнивания Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌΡƒ адрСсу Π² памяти.

ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏΡ‹, Π° Π·Π°Ρ‚Π΅ΠΌ Ρ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΈ записывайтС Π΄Π°Π½Π½Ρ‹Π΅ с использованиСм ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² вмСсто Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ Π±ΠΈΡ‚Π°ΠΌΠΈ, словами ΠΈ адрСсами. МодСль памяти Π‘++ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π½Π΅ заставляя вас ΠΏΡ€ΠΈ этом Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с прСдставлСниями Π΄Π°Π½Π½Ρ‹Ρ… Π² памяти. Π’Π°ΠΊ ΠΈ Π½Π΅ Π΄Π΅Π»Π°ΠΉΡ‚Π΅ этого.

Бсылки

[Dewhurst03] Β§95

92. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ reinterpret_cast

РСзюмС

Как гласит римская пословица, Ρƒ Π»ΠΆΠΈ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠ΅ Π½ΠΎΠ³ΠΈ. НС ΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ reinterpret_cast, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ компилятор Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ Π±ΠΈΡ‚Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΊΠ°ΠΊ Π±ΠΈΡ‚Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π’Π°ΠΊΠΎΠ΅ дСйствиС ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ бСзопасности Ρ‚ΠΈΠΏΠΎΠ².

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

ВспомнитС: Если Π²Ρ‹ Π»ΠΆΠ΅Ρ‚Π΅ компилятору, ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΡΡ‚ΠΈΡ‚ΡŒ (Π“Π΅Π½Ρ€ΠΈ БпСнсСр).

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ reinterpret_cast ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ прСдставлСния программиста ΠΎ прСдставлСнии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² памяти, Ρ‚.Π΅. программист Π±Π΅Ρ€Π΅Ρ‚ Π½Π° сСбя ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π·Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π»ΡƒΡ‡ΡˆΠ΅ компилятора Π·Π½Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Ρ‡Ρ‚ΠΎ нСльзя. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ ΠΌΠΎΠ»Ρ‡Π° сдСлаСт Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π΅ΠΌΡƒ скаТСтС, Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ Π³Ρ€ΡƒΠ±ΡƒΡŽ силу Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡΡ… с компилятором β€” послСднСС Π΄Π΅Π»ΠΎ. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΎ прСдставлСнии Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΊΠΈΠ΅ прСдполоТСния ΠΎΡ‡Π΅Π½ΡŒ сильно Π²Π»ΠΈΡΡŽΡ‚ Π½Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ вашСго ΠΊΠΎΠ΄Π°.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ²Π°, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ примСнСния reinterpret_cast Π΅Ρ‰Π΅ Ρ…ΡƒΠΆΠ΅, Ρ‡Π΅ΠΌ просто Π½Π°ΡΠΈΠ»ΡŒΡΡ‚Π²Π΅Π½Π½Π°Ρ интСрпрСтация Π±ΠΈΡ‚ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (Ρ‡Ρ‚ΠΎ само ΠΏΠΎ сСбС достаточно Π½Π΅Ρ…ΠΎΡ€ΠΎΡˆΠΎ). Π—Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΠΌΡ‹Ρ… ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ reinterpret_cast зависит ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π΄Π°ΠΆΠ΅ Π½Π΅ Π·Π½Π°Π΅Ρ‚Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ, ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠ΅ ΠΈ нСпСрСносимоС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅.

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

НСкоторыС Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹Π΅ спСцифичныС для Π΄Π°Π½Π½ΠΎΠΉ систСмы ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ вас ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ reinterpret_cast ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΡƒ Π±ΠΈΡ‚ΠΎΠ², проходящих Ρ‡Π΅Ρ€Π΅Π· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚, ΠΈΠ»ΠΈ для прСобразования Ρ†Π΅Π»Ρ‹Ρ… чисСл Π² адрСса. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ‚Π°ΠΊΠΎΠ΅ нСбСзопасноС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΠΆΠ΅ ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ скрытых Π·Π° абстракциями функциях, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ваш ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚ΡŒ с ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ измСнСниями. Если Π²Π°ΠΌ трСбуСтся ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ указатСлями нСсвязанных Ρ‚ΠΈΠΏΠΎΠ², Π»ΡƒΡ‡ΡˆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π΅Π³ΠΎ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΊ void* вмСсто нСпосрСдствСнного использования reinterpret_cast, Ρ‚.Π΅. вмСсто ΠΊΠΎΠ΄Π°

T1* p1 = ... ;

T2* p2 = reinterpret_cast<T2*>(p1);

Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ

T1* p1 = ...;

void* pV = p1;

T2* p2 = static_cast<T2*>(pV);

Бсылки

[Π‘++03] Β§5.2.10(3) β€’ [Dewhurst03] Β§39 β€’ [Stroustrup00] Β§5.6

93. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ примСнСния static_cast ΠΊ указатСлям

РСзюмС

К указатСлям Π½Π° динамичСскиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π΅ слСдуСт ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ static_cast. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ бСзопасныС Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹ β€” ΠΎΡ‚ dynamic_cast Π΄ΠΎ пСрСпроСктирования.

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

ΠŸΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ ΠΎ Π·Π°ΠΌΠ΅Π½Π΅ static_cast Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΡ‰Π½Ρ‹ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ dynamic_cast, ΠΈ Π²Π°ΠΌ Π½Π΅ придСтся Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, Π² ΠΊΠ°ΠΊΠΈΡ… случаях ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ static_cast бСзопасно, Π° Π² ΠΊΠ°ΠΊΠΈΡ… β€” Ρ‡Ρ€Π΅Π²Π°Ρ‚ΠΎ нСприятностями. Π₯отя dynamic_cast ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΅ эффСктивным ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ позволяСт ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ Π½Π΅Π²Π΅Ρ€Π½Ρ‹Π΅ прСобразования Ρ‚ΠΈΠΏΠΎΠ² (Π½ΠΎ Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΎ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ 8). ИспользованиС static_cast вмСсто dynamic_cast Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ экономию Π½Π° Π½ΠΎΡ‡Π½ΠΎΠΌ освСщСнии, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ΠΈΠ³Ρ€Ρ‹Ρˆ Π΄ΠΎΠ»Π»Π°Ρ€Π° Π² Π³ΠΎΠ΄ оборачиваСтся ΠΏΠ΅Ρ€Π΅Π»ΠΎΠΌΠ°Π½Π½Ρ‹ΠΌΠΈ Π½ΠΎΠ³Π°ΠΌΠΈ.

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

Π§Ρ€Π΅Π·ΠΌΠ΅Ρ€Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ½ΠΈΠΆΠ°ΡŽΡ‰Π΅Π³ΠΎ привСдСния ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠΎΠΌ слишком Π±Π΅Π΄Π½ΠΎΠ³ΠΎ интСрфСйса Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. Π’Π°ΠΊΠΎΠΉ интСрфСйс ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ большая Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ опрСдСляСтся Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹Ρ… классах, ΠΈ всякий Ρ€Π°Π· ΠΏΡ€ΠΈ нСобходимости Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ интСрфСйса приходится ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ½ΠΈΠΆΠ°ΡŽΡ‰Π΅Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅. Одно ΠΈΠ· Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ Π΄Π°Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ β€” ΠΏΠ΅Ρ€Π΅ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ интСрфСйса Π² цСлях ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Π’ΠΎΠ³Π΄Π° ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° становятся сущСствСнны Π½Π°ΠΊΠ»Π°Π΄Π½Ρ‹Π΅ расходы, Π²Ρ‹Π·Π²Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ dynamic_cast (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 8), слСдуСт ΠΏΠΎΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ собствСнного прСобразования Ρ‚ΠΈΠΏΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ dynamic_cast ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ ΠΈ static_cast Π² ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ вСрсии (см. [Stroustrup00]):

template<class To, class From> To checked_cast(From* from) {

 assert(dynamic_cast<To>(from) ==

  static_cast<To>(from) && "checked_cast failed" );

 return static_cast<To>(from);

}


template<class To, class From> To checked_cast(From& from) {

 typedef tr1::remove_reference<To>::type* ToPtr; // [C++TR104]

 assert(dynamic_cast<ToPtr>(&from) ==

  static_cast<ToPtr>(&from) && "checked_cast failed");

 return static_cast<To>(from);

}

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

Бсылки

[Dewhurst03] Β§29, Β§35, Β§41 β€’ [Meyers97] Β§39 β€’ [Stroustrup00] Β§13.6.2 β€’ [Sutter00] Β§44

94. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ, ΠΎΡ‚ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΡ… const

РСзюмС

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ², ΠΎΡ‚ΠΌΠ΅Π½ΡΡŽΡ‰Π΅Π΅ const, ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ повСдСнию, Π° ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, это ΡΠ²ΠΈΠ΄Π΅Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ ΠΏΠ»ΠΎΡ…ΠΎΠ³ΠΎ стиля программирования Π΄Π°ΠΆΠ΅ Π² Ρ‚ΠΎΠΌ случаС, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΎΠ³ΠΎ прСобразования Π²ΠΏΠΎΠ»Π½Π΅ Π·Π°ΠΊΠΎΠ½Π½ΠΎ.

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

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ const β€” это Π΄ΠΎΡ€ΠΎΠ³Π° с односторонним Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΈ, воспользовавшись этим спСцификатором, Π²Ρ‹ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄Π°Π²Π°Ρ‚ΡŒ Π·Π°Π΄Π½ΠΈΠΉ Ρ…ΠΎΠ΄. Если Π²Ρ‹ отмСняСтС const для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π±Ρ‹Π» объявлСн ΠΊΠ°ΠΊ константный, Π·Π°Π΄Π½ΠΈΠΉ Ρ…ΠΎΠ΄ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ вас Π½Π° Ρ‚Π΅Ρ€Ρ€ΠΈΡ‚ΠΎΡ€ΠΈΡŽ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ повСдСния. НапримСр, компилятор ΠΌΠΎΠΆΠ΅Ρ‚ (ΠΈ, Π±Ρ‹Π²Π°Π΅Ρ‚, Ρ‚Π°ΠΊ ΠΈ поступаСт) ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ константныС Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния (ROM) ΠΈΠ»ΠΈ Π² страницы памяти, Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹Π΅ ΠΎΡ‚ записи. ΠžΡ‚ΠΊΠ°Π· ΠΎΡ‚ const Ρƒ Ρ‚Π°ΠΊΠΎΠ³ΠΎ истинно константного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° β€” прСступный ΠΎΠ±ΠΌΠ°Π½, Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΊΠ°Ρ€Π°Π΅ΠΌΡ‹ΠΉ Π°Π²Π°Ρ€ΠΈΠΉΠ½Ρ‹ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ·-Π·Π° Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ памяти.

Π”Π°ΠΆΠ΅ Ссли ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ ΠΏΠΎΡ‚Π΅Ρ€ΠΏΠΈΡ‚ ΠΊΡ€Π°Ρ…, ΠΎΡ‚ΠΌΠ΅Π½Π° const прСдставляСт собой ΠΎΡ‚ΠΌΠ΅Π½Ρƒ ΠΎΠ±Π΅Ρ‰Π°Π½Π½ΠΎΠ³ΠΎ ΠΈ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Π΅Π³ΠΎ ΠΎΡ‚ Π½Π΅Π΅ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚. НапримСр, Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ Π½Π΅ происходит выдСлСния массива ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹:

void Foolish(unsigned int n) {

 const unsigned int size = 1;

 const_cast<unsigned int&>(size) = n; // НС Π΄Π΅Π»Π°ΠΉΡ‚Π΅ Ρ‚Π°ΠΊ!

 char buffer[size];                   // Π Π°Π·ΠΌΠ΅Ρ€ массива

 // ...                               // всС Ρ€Π°Π²Π½ΠΎ Ρ€Π°Π²Π΅Π½ 1

}

Π’ Π‘++ имССтся ΠΎΠ΄Π½ΠΎ нСявноС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ const_cast ΠΈΠ· строкового Π»ΠΈΡ‚Π΅Ρ€Π°Π»Π° Π² char*:

char* weird = "Trick or treat?";

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ ΠΌΠΎΠ»Ρ‡Π° выполняСт ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ const_cast ΠΈΠ· const char[16] Π² char*. Π­Ρ‚ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΎ для совмСстимости с API Π² стилС Π‘, хотя ΠΈ прСдставляСт собой Π΄Ρ‹Ρ€Ρƒ Π² систСмС Ρ‚ΠΈΠΏΠΎΠ² Π‘++. Π‘Ρ‚Ρ€ΠΎΠΊΠΎΠ²Ρ‹Π΅ Π»ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ Π² памяти Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния, ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° измСнСния Ρ‚Π°ΠΊΠΎΠΉ строки ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ памяти.