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

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

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

Π“Π»Π°Π²Π° 15

Π Π°Π·Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

15.0. Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Π’ этой Π³Π»Π°Π²Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ аспСкты C++, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ»ΠΎΡ…ΠΎ Π²ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΡƒ любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π³Π»Π°Π²Ρ‹: ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ Ρ‡Π»Π΅Π½ΠΎΠ², константныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ- Ρ‡Π»Π΅Π½Ρ‹, нСзависимыС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ (Ρ‚.Π΅. Π½Π΅ Ρ‡Π»Π΅Π½Ρ‹ класса) ΠΈ нСсколько Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚Π΅ΠΌ.

15.1. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для ΠΈΡ… ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°

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

ΠŸΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ использованиС Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ func1, которая Π½Π° этапС выполнСния Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ func2. Однако ΠΏΠΎ Ρ‚ΠΎΠΉ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ нСльзя Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ func1 ТСстко Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ имя Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ func2. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, имя Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ func2 нСизвСстно Π½Π° этапС компиляции, ΠΈΠ»ΠΈ func1 относится ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌΡƒ интСрфСйсу нСзависимого Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, ΠΈ ΠΎΠ½Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π° ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π° Π’ любом случаС Π²Π°ΠΌ придСтся Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° (callback function).

РСшСниС

ΠŸΡ€ΠΈ использовании ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π²Ρ‹ΡˆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ func1 с ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² качСствС своСго Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ Π΅ΠΉ адрСс func2 Π½Π° этапС выполнСния. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ typedef, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π»Π΅Π³Ρ‡Π΅ Ρ‡ΠΈΡ‚Π°Π»Π°ΡΡŒ ΠΈ ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Π»Π°ΡΡŒ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.1 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.1. Ѐункция ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°

#include <iostream>


// ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°

bool updateProgress(int pct) {

 std::cout << pct << "% complete...\n";

 return(true);

}


// Π­Ρ‚ΠΎΡ‚ typedef Π΄Π΅Π»Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ понятным

typedef bool (*FuncPtrBoolInt)(int);


// Ѐункция, которая выполняСтся достаточно Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ врСмя

void longOperation(FuncPtrBoolInt f) {

 for (long l=0; l < 100000000; l++)

 if (l % 10000000 == 0)

 f(l/1000000);

}


int main() {

 longOperation(updateProgress); // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ

}

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

Π’ ситуации, которая ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.1, ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ указатСля Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ являСтся Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ, Ссли UpdateProgress ΠΈ longOperation Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π½Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ ΠΎ Π΄Ρ€ΡƒΠ³Π΅. НапримСр, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая обновляСт ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ‚ΠΎΡ€ состояния процСсса Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ интСрфСйса (user interface β€” UI), Π² ΠΎΠΊΠ½Π΅ консольного Ρ€Π΅ΠΆΠΈΠΌΠ° ΠΈΠ»ΠΈ Π³Π΄Π΅-Ρ‚ΠΎ Π΅Ρ‰Π΅, Π½Π΅ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ контСкст, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½Π° вызываСтся. Аналогично функция longOperation ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒΡŽ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ интСрфСйса Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½Π΅ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ мСсто Π²Ρ‹Π·ΠΎΠ²Π°: ΠΈΠ· графичСского UI, ΠΈΠ· ΠΎΠΊΠ½Π° консольного Ρ€Π΅ΠΆΠΈΠΌΠ° ΠΈΠ»ΠΈ ΠΈΠ· Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠ³ΠΎ процСсса.

Π‘Π½Π°Ρ‡Π°Π»Π° потрСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ сигнатуру Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π²Ρ‹ ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ, ΠΈ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ для Π½Π΅Π΅ typedef. ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ typedef β€” ваш ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ Π² Ρ‚Π΅Ρ… случаях, ΠΊΠΎΠ³Π΄Π° приходится ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ с указатСлями Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ синтаксис. Рассмотрим, ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ Ρ‚Π°ΠΊΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ f, которая содСрТит адрСс Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ СдинствСнный Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ†Π΅Π»ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π΅ΠΉ значСния Ρ‚ΠΈΠΏΠ° boolean. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ

bool (*f)(int); // f - имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ справСдливо Π²ΠΎΠ·Ρ€Π°Π·ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ здСсь Π½Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ особСнного ΠΈ я просто излишнС Π΄Ρ€Π°ΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΡƒΡŽ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ. Но Ρ‡Ρ‚ΠΎ Π²Ρ‹ скаТСтС, Ссли трСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π²Π΅ΠΊΡ‚ΠΎΡ€ vector Ρ‚Π°ΠΊΠΈΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ?

vector<bool (*)(int)> vf;

Или ΠΈΡ… массив?

bool (*af[10])(int);

Π€ΠΎΡ€ΠΌΠ° прСдставлСния ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ отличаСтся ΠΎΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π‘++, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π·Π°Π΄Π°ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅ (ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ) ΠΈΠΌΠ΅Π½ΠΈ Ρ‚ΠΈΠΏΠ°, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΈΠ΄Π΅Ρ‚ имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΎΠ½ΠΈ вносят ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρƒ ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.

Π˜Ρ‚Π°ΠΊ, Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.1 я использовал ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ typedef.

typedef bool (*FuncPtrBoolInt)(int);

Π‘Π΄Π΅Π»Π°Π² это, я ΠΌΠΎΠ³Ρƒ свободно ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ с сигнатурой, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π΅ΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ bool ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ СдинствСнный Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΊΠ°ΠΊ это я Π±Ρ‹ Π΄Π΅Π»Π°Π» для ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° любого Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

void longOperation(FuncPtrBoolInt f) { // ...

Π’Π΅ΠΏΠ΅Ρ€ΡŒ всС, Ρ‡Ρ‚ΠΎ Π½Π°Π΄ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π² longOperation, β€” это Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ f, ΠΊΠ°ΠΊ Ссли Π±Ρ‹ это Π±Ρ‹Π»Π° любая обычная функция.

f(l/1000000);

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

bool whoCares(int i) {return(true);}

//...

longOperation(whoCares);

Π‘ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π±ΠΎΡ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠΉ longOperation, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒΡΡ динамичСски Π½Π° этапС выполнСния.

15.2. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ для Ρ‡Π»Π΅Π½ΠΎΠ² класса

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

ВрСбуСтся ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π°Π΄Ρ€Π΅ΡΠ½ΡƒΡŽ ссылку Π½Π° Π΄Π°Π½Π½ΠΎΠ΅-Ρ‡Π»Π΅Π½ ΠΈΠ»ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½.

РСшСниС

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ имя класса ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ области видимости (::) со Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΠΎΠΉ для ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ квалифицирования ΠΈΠΌΠ΅Π½ΠΈ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.2 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 15.2. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ указатСля Π½Π° Ρ‡Π»Π΅Π½ класса

#include <iostream>

#include <string>


class MyClass {

public:

 MyClass() : ival_(0), sval_("foo") {}

 ~MyClass() {}

 void incr() {++ival_;}

 void decr() {ival_--;}

private:

 std::string sval_;

 int ival_;

};


int main() {

 MyClass obj;

 int MyClass::* mpi = &MyClass::ival_;         // Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π°

 std::string MyClass::* mps = &MyClass::sval_; // Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹

 void (MyClass::*mpf)(); // Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ

                         // Π½Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈ которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ void

 void (*pf)(); // ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

 int* pi = &obj.ival_; // int-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΡΡΡ‹Π»Π°ΡŽΡ‰ΠΈΠΉΡΡ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ-Ρ‡Π»Π΅Π½

                       // Ρ‚ΠΈΠΏΠ° int, - всС Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ.

 mpf = &MyClass::incr; // Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½. Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅

                       // Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² ΠΏΠΎΡ‚ΠΎΠΊ. ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π²

                       // ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ΅, ΠΊΠ°ΠΊ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ выглядит.

 pf = &MyClass::incr; // Ошибка: &MyClass::inc Π½Π΅ являСтся экзСмпляром

                      // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

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

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

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

 std::cout << "*pi = " << *pi << '\n';

 obj.*mpi = 5;

 obj.*mps = "bar";

 (obj.*mpf)(); // Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ obj.ival_ Ρ€Π°Π²Π½ΠΎ 6

 std::cout << "obj.ival_ = " << obj.ival_ << '\n';

 std::cout << "obj.sval_ = " << obj.sval_ << '\n';

}

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

Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Ρ‡Π»Π΅Π½Ρ‹ класса выглядят ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΈΠ½Π°Ρ‡Π΅, Ρ‡Π΅ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ. ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ «смСшной» синтаксис (Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ смСх, Π½ΠΎ странный). Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 15.2.

int MyClass::* mpi = &MyClass::ival_;

Π—Π΄Π΅ΡΡŒ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΈ Π΅ΠΌΡƒ присваиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ†Π΅Π»ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ оказываСтся Ρ‡Π»Π΅Π½ класса MyClass. Π”Π²Π΅ Π²Π΅Ρ‰ΠΈ ΠΎΡ‚Π½ΠΈΠΌΠ°ΡŽΡ‚ это объявлСниС ΠΎΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ int*. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π²Π°ΠΌ приходится Π²ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ имя класса ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ области видимости ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚ΠΈΠΏΠΎΠΌ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΈ Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΠΎΠΉ. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ присваивания этому ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ Π½Π° самом Π΄Π΅Π»Π΅ Π½Π΅ назначаСтся ΠΊΠ°ΠΊΠΎΠΉ Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ адрСс памяти. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ &MyClass::ival_ Π½Π΅ являСтся ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, содСрТащимся Π² памяти; ΠΎΠ½ΠΎ ссылаСтся Π½Π° имя класса, Π° Π½Π΅ Π½Π° имя ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π° Ρ‡Ρ‚ΠΎ ΠΆΠ΅ это Ρ‚Π°ΠΊΠΎΠ΅ Π½Π° самом Π΄Π΅Π»Π΅? МоТно ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ смСшСниС Π΄Π°Π½Π½ΠΎΠ³ΠΎ-Ρ‡Π»Π΅Π½Π° ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ адрСса ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ mpi Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ совмСстно с экзСмпляром класса, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½Π° примСняСтся. НСмного Π½ΠΈΠΆΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.2 располагаСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ строка, которая ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ mpi для присваивания Ρ†Π΅Π»ΠΎΠ³ΠΎ числа Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ссылаСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ mpi.

obj.*mpi = 5;

obj являСтся экзСмпляром класса MyClass. Бсылка Π½Π° Ρ‡Π»Π΅Π½ с использованиСм Ρ‚ΠΎΡ‡ΠΊΠΈ (ΠΈΠ»ΠΈ ->, Ссли Ρƒ вас имССтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° obj) ΠΈ Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ mpi ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π²Π°ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ссылку Π½Π° obj.ival_.

Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ фактичСски Ρ‚Π°ΠΊ ΠΆΠ΅. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 15.2 ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ MyClass, которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ void ΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

void (MyClass::*mpf)();

Π•ΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° адрСсации.

mpf = &MyClass::incr;

Для Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ основноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² скобки, Ρ‡Ρ‚ΠΎΠ±Ρ‹ компилятор понял ваши намСрСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

(obj.*mpf)();

Однако имССтся ΠΎΠ΄Π½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ‡Π»Π΅Π½Ρ‹. Если Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ (Π½Π΅ Π½Π° Ρ‡Π»Π΅Π½ класса) Π½Π° Π΄Π°Π½Π½ΠΎΠ΅-Ρ‡Π»Π΅Π½, просто дСйствуйтС ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.