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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«C++. Π‘Π±ΠΎΡ€Π½ΠΈΠΊ Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 134

Автор Π”. БтСфСнс

int* pi = &obj.ival_;

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ имя ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π° Π½Π΅ имя класса, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ адрСс ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π΄Π°Π½Π½ΠΎΠ³ΠΎ-Ρ‡Π»Π΅Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, располоТСнного Π³Π΄Π΅-Ρ‚ΠΎ Π² памяти. (Однако ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΡΡ‚Π°Ρ€Π°ΡŽΡ‚ΡΡ адрСса Π΄Π°Π½Π½Ρ‹Ρ…-Ρ‡Π»Π΅Π½ΠΎΠ² класса Π½Π΅ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ Π·Π° Π΅Π³ΠΎ ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ нСльзя Π±Ρ‹Π»ΠΎ ΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΠ·-Π·Π° ΠΎΠΏΡ€ΠΎΠΌΠ΅Ρ‚Ρ‡ΠΈΠ²Ρ‹Ρ… дСйствий Π² клиСнтском ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅.)

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‡Π»Π΅Π½Π° с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это бСссмыслСнно. Рассмотрим ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΈΠΌΠ΅ΡŽΡ‰ΡƒΡŽ Ρ‚Π°ΠΊΡƒΡŽ ΠΆΠ΅ сигнатуру, ΠΊΠ°ΠΊ MyClass::incr (Ρ‚.Π΅. ΠΎΠ½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ void ΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²).

void (*pf)();

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ этому ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ адрСс Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π°.

pf = &MyClass::incr; // He получится

pf = &obj.incr;      // И это Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Ρ‚

ОбС эти строки Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹, ΠΈ Π½Π° это ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ вСскиС основания. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π·ΡƒΠΌΠ½Ρ‹ΠΉ смысл Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² контСкстС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ, вСроятнСС всСго, ΠΎΠ½Π° Π΄ΠΎΠ»ΠΆΠ½Π° ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹. Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° Π±Π΅Π· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΠ·Π½Π°Ρ‡Π°Π»ΠΎ Π±Ρ‹ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ Ρ‡Π»Π΅Π½Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π° эта функция, ΠΏΠΎ-Π²ΠΈΠ΄ΠΈΠΌΠΎΠΌΡƒ, ΠΊΠ°ΠΊ Ρ€Π°Π· являСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ, Π° Π½Π΅ Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‡Π»Π΅Π½Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Π‘ΠΌ. Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚ 15.1.

15.3. ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡Π΅Π½ΠΈΠ΅ нСвозмоТности ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

Π’Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ трСбуСтся Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π΅Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅.

РСшСниС

Для прСдотвращСния измСнСния Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ с ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ словом const. ΠšΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 15.3 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.3. Гарантия нСвозмоТности ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²

#include <iostream

#include <string>


void concat(const std::string& s1, // АргумСнты ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ ΠΊΠ°ΠΊ константноС,

 const std::string& s2,            // поэтому Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹

 std::string& out) {

 out = s1 + s2;

}


int main() {

 std::string s1 = "Cabo ";

 std::string s2 = "Wabo";

 std::string s3;

 concat(s1, s2, s3);

 std::cout << "s1 = " << s1 << '\n';

 std::cout << "s2 = " << s2 << '\n';

 std::cout << "s3 = " << s3 << '\n';

}

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

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.3 продСмонстрировано прямоС использованиС ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова const. БущСствуСт Π΄Π²Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ объявлСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с этим ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ словом, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π½Π΅ ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, этим Π²Ρ‹ сообщаСтС ΠΎ своих намСрСниях читатСлям вашСго ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Объявляя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΊΠ°ΠΊ const, Π²Ρ‹ фактичСски Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΎΠ½ являСтся Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ. Π­Ρ‚ΠΎ позволяСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² расчСтС Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ эти значСния Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, это позволяСт компилятору Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π° Ρ‚ΠΎΡ‚ случай, Ссли Π²Ρ‹ случайно ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅. Рассмотрим Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ concat ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 15 3.

void concatUnsafe(std::string& s1,

 std::string& s2 std::string& out) {

 out = s1 += s2; // Ну Π²ΠΎΡ‚, записано Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² s1

}

НСсмотря Π½Π° мою ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡ΠΊΡƒ Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, я сдСлал Π³Π»ΡƒΠΏΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΈ написал += вмСсто +. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ concatUnsafe Π±ΡƒΠ΄ΡƒΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ out ΠΈ s1, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΡΡŽΡ€ΠΏΡ€ΠΈΠ·ΠΎΠΌ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΅Π΄Π²Π° Π»ΠΈ рассчитываСт Π½Π° ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· исходных строк.

Бпасти ΠΌΠΎΠΆΠ΅Ρ‚ const. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ concatSafe, ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ константными, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.3, ΠΈ функция Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π°.

void concatSafe(const std::string& s1,

 const std::string& s2, std::string& out) {

 out = s1 += s2; // Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡˆΠΈΠ±ΠΊΡƒ компиляции

}

concatSafΠ΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² s1 ΠΈ s2. Π­Ρ‚Π° функция Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Ρ‰Π΅ ΠΊΠΎΠ΅-Ρ‡Ρ‚ΠΎ: ΠΎΠ½Π° позволяСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ константныС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹. НапримСр, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΡŽ строк, ΠΌΠΎΠ³ Π±Ρ‹ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

void myFunc(const std::string& s) { // ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ s являСтся

                                    // константной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ

 std::string dest;

 std::string tmp = "foo";

 concatUnsafe(s, tmp, dest); // Ошибка: s - константная пСрСмСнная

                             // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ дСйствия с dest...

}

Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС функция myFunc Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ concatUnsafe Π½Π΅ обСспСчиваСт const'Π°Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ myFunc. myFunc Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π²Π½Π΅ΡˆΠ½Π΅ΠΌΡƒ ΠΌΠΈΡ€Ρƒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ содСрТимоС s, Ρ‚.Π΅. всС дСйствия с s Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅Π»Π° myFunc Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π½Π°Ρ€ΡƒΡˆΠ°Ρ‚ΡŒ это ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ это ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ const_cast ΠΈ Ρ‚Π΅ΠΌ самым освобоТдаясь ΠΎΡ‚ константности, Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΅Π½, ΠΈ Π΅Π³ΠΎ слСдуСт ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ. Π’ этой ситуации concatSafe Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ.

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

void concatUnsafePtr(std::string* ps1,

 std::string* ps2, std::string* pout) {

 *pout = *ps1 + *ps2;

}

Π—Π΄Π΅ΡΡŒ такая ΠΆΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ с concatUnsafe, описанном Ρ€Π°Π½Π΅Π΅. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ const для Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ нСвозмоТности обновлСния исходных строк.

void concatSaferPtr(const std::string* ps1,

 const std::string* ps2, std::string* pout) {

 *pout = *ps1 + *ps2;

}

ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ *ps1 ΠΈ *ps2. Но Π²Ρ‹ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ps1 ΠΈ ps2, ΠΈΠ»ΠΈ, Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΈΡ…, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΡΠ»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΊΠ°ΠΊΡƒΡŽ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΡƒΡŽ строку, измСняя Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ указатСля, Π½ΠΎ Π½Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠ½ ссылаСтся. Ничто Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠ΅ΡˆΠ°Ρ‚ΡŒ Π²Π°ΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅.

void concatSaferPtr(const std:string* ps1,

 const std::string* ps2, std::string* pout) {

 ps1 = pout; // Π£Ρ…!

 *pout = *ps1 + *ps2;

}

ΠŸΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ ошибки ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ const.

void concatSafestPtr(const std::string* const ps1,

 const std::string* const ps2, std::string* pout) {

 *pout = *ps1 + *ps2;

}

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

Π‘ΠΌ. Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚ 15.4.

15.4. ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡Π΅Π½ΠΈΠ΅ нСвозмоТности ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ своих ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π΅

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

ВрСбуСтся Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ -Ρ‡Π»Π΅Π½Ρ‹ для константного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π½ΠΎ ваш компилятор ТалуСтся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Π²Π°ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ· константного Π² нСконстантный.

РСшСниС

ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚Π΅ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово const справа ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° ΠΏΡ€ΠΈ Π΅Π΅ объявлСнии Π² классС ΠΈ ΠΏΡ€ΠΈ Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.4 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.4. ОбъявлСниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° константной

#include <iostream>

#include <string>


class RecordSet {

public:

 bool getFieldVal(int i, std::string& s) const;

 // ...

};


bool RecordSet::getFieldVal(int i, std::string& s) const {

 // Π—Π΄Π΅ΡΡŒ нСльзя ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ нСизмСняСмыС

 // Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ (см. обсуТдСниС)

}


void displayRecords(const RecordSet& rs) {

 // Π—Π΄Π΅ΡΡŒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ константныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹

 // для rs

}

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

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ†Π΅Π²ΠΎΠ³ΠΎ const Π² объявлСниС Ρ‡Π»Π΅Π½Π° ΠΈ Π² Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ заставляСт компилятор Π±ΠΎΠ»Π΅Π΅ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚Π½Π΅ΡΡ‚ΠΈΡΡŒ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ дСлаСтся с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅Π»Π° Ρ‡Π»Π΅Π½Π°. ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Π½Ρ‹ΠΌ функциям-Ρ‡Π»Π΅Π½Π°ΠΌ Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ нСконстантныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ-Ρ‡Π»Π΅Π½Π°ΠΌΠΈ. Если Ρ‚Π°ΠΊΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚, компиляция Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎ. НапримСр, Ссли Π±Ρ‹ Π² RecordSet::getFieldVal я ΠΎΠ±Π½ΠΎΠ²ΠΈΠ» счСтчик-Ρ‡Π»Π΅Π½, эта функция Π½Π΅ Π±Ρ‹Π»Π° Π±Ρ‹ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π° (Π² ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Ρ‡Ρ‚ΠΎ getFieldCount_ являСтся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ класса RecordSet).

bool RecordSet::getFieldVal(int i, std::string& s) const {

 ++getFieldCount_; // Ошибка: константная функция-Ρ‡Π»Π΅Π½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚

                   // ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ-Ρ‡Π»Π΅Π½

                   // ...

}

Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΈΠ΅ ошибки, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ const Π² Ρ€ΠΎΠ»ΠΈ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ (см. Ρ€Π΅Ρ†Π΅ΠΏΡ‚ 15.3). Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Π³Π»ΡƒΠΏΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ.