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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ использованиС C++. 55 Π²Π΅Ρ€Π½Ρ‹Ρ… способов ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ структуру ΠΈ ΠΊΠΎΠ΄ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 46

Автор Π‘ΠΊΠΎΡ‚Ρ‚ ΠœΠ°ΠΉΠ΅Ρ€Ρ

Идиома NVI Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π±Ρ‹Π»ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌΠΈ. Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… иСрархиях классов оТидаСтся, Ρ‡Ρ‚ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция, пСрСопрСдСлСнная Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ классС, Π±ΡƒΠ΄Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса (ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ»Π° 27). Π§Ρ‚ΠΎΠ±Ρ‹ Ρ‚Π°ΠΊΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π±Ρ‹Π»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹, Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ функция Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΉ, Π° Π½Π΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΉ. Иногда ΠΎΠ½Π° Π΄Π°ΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΉ (ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, дСструкторы Π² ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½Ρ‹Ρ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классах – см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 7), Π½ΠΎ ΠΊ этому ΡΠ»ΡƒΡ‡Π°ΡŽ ΠΈΠ΄ΠΈΠΎΠΌΠ° NVI ΡƒΠΆΠ΅ Π½Π΅ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠ°.

РСализация ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° «БтратСгия» посрСдством ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

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


class GameCharacter; // ΠΎΠΏΠ΅Ρ€Π΅ΠΆΠ°ΡŽΡ‰Π΅Π΅ объявлСниС

// функция Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы пСрсонаТа

int defaultHealthCalc(const GameCharacter& gc);

class GameCharacter {

public:

typedef int (*HealthCalcFunc)(const GameCharacter&);

explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)

: healthFunc(hcf)

{}

int healthValue() const

{ return healthFunc(*this);}

...

private:

HealthCalcFunc healthFunc;

};


Π­Ρ‚ΠΎ простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€ примСнСния Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ распространСнного ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° проСктирования – «БтратСгия» (Strategy). По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°ΠΌΠΈ, основанными Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… функциях Π² ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ GameCharacter, ΠΎΠ½ прСдоставляСт Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π»ΡŽΠ±ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Π΅ возмоТности, ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠ΅ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ:

β€’ Π Π°Π·Π½Ρ‹Π΅ экзСмпляры пСрсонаТСй ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ‚ΠΈΠΏΠ° ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы. НапримСр:


class EvilBadGay: public GameCharacter {

public:

explicit EvilBadGay(HealthCalcFunc hcf = defaultHealthCalc)

: GameCharacter(hcf)

{...}

...

};

int loseHealthQuickly(const GameCharacter&); // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ вычислСния

int loseHealthSlowly(const GameCharacter&); // ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы

// с Ρ€Π°Π·Π½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ

EvilBadGay ebg1(loseHealthQuickly); // ΠΎΠ΄Π½ΠΎΡ‚ΠΈΠΏΠ½Ρ‹Π΅ пСрсонаТи

EvilBadGay ebg2(loseHealthSlowly); // с Ρ€Π°Π·Π½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ

// ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΡ


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

Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, Ρ‚ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ функция вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы большС Π½Π΅ являСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ GameCharacter, ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ доступа ΠΊ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ‡ΡŒΡŽ ΠΆΠΈΠ·Π½Π΅Π½Π½ΡƒΡŽ силу вычисляСт. НапримСр, defaultHealthCalc Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ доступа ΠΊ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ частям EvilBadGay. Π­Ρ‚ΠΎ Π½Π΅ ΡΡ‚Ρ€Π°ΡˆΠ½ΠΎ, Ссли ТизнСнная сила пСрсонаТа ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ вычислСна с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΅Π³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ интСрфСйса, Π½ΠΎ для максимально Ρ‚ΠΎΡ‡Π½Ρ‹Ρ… расчСтов ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ доступ ΠΊ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ. На самом Π΄Π΅Π»Π΅ такая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Ρ‚ΡŒ всСгда, ΠΊΠΎΠ³Π΄Π° нСкоторая Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ выносится ΠΈΠ· класса Π½Π°Ρ€ΡƒΠΆΡƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² Π² свободныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ Π΄Ρ€ΡƒΠ·ΡŒΡΠΌΠΈ класса, ΠΈΠ»ΠΈ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ класса, Π½Π΅ друТСствСнного Π΄Π°Π½Π½ΠΎΠΌΡƒ). Она Π±ΡƒΠ΄Π΅Ρ‚ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Ρ‚ΡŒΡΡ Π² настоящСм ΠΏΡ€Π°Π²ΠΈΠ»Π΅ ΠΈ Π΄Π°Π»Π΅Π΅, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ всС ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°ΠΌ Π΅Ρ‰Π΅ прСдстоит Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Ρ‚ΠΎΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, находящихся Π²Π½Π΅ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ GameCharacter.

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

РСализация ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° «БтратСгия» посрСдством класса tr::function

Если Π²Ρ‹ ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ»ΠΈ ΠΊ шаблонам ΠΈ ΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡŽ для построСния нСявных интСрфСйсов (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 41), Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ покаТСтся Π²Π°ΠΌ Π½Π΅ слишком Π³ΠΈΠ±ΠΊΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ. ΠŸΠΎΡ‡Π΅ΠΌΡƒ Π²ΠΎΠΎΠ±Ρ‰Π΅ для вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π° Π½Π΅ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Π΅Π΄ΡƒΡ‰Π΅Π΅ сСбя ΠΊΠ°ΠΊ функция (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚)? Если ΠΎΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½ΠΈΠΊΡƒΠ΄Π° Π½Π΅ Π΄Π΅Ρ‚ΡŒΡΡ, Ρ‚ΠΎ ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π΅ Ρ‡Π»Π΅Π½ΠΎΠΌ класса? И ΠΏΠΎΡ‡Π΅ΠΌΡƒ функция Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ int, Π° Π½Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π² int?

Π­Ρ‚ΠΈ ограничСния ΠΈΡΡ‡Π΅Π·Π°ΡŽΡ‚, Ссли вмСсто указатСля Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ (ΠΏΠΎΠ΄ΠΎΠ±Π½ΡƒΡŽ healthFunc) Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Ρ‚ΠΈΠΏΠ° tr::function. Как ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 54, Ρ‚Π°ΠΊΠΎΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡƒΡŽ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ (ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π»ΠΈΠ±ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½), Ρ‡ΡŒΡ сигнатура совмСстима с ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠΉ. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°, Π½Π° этот Ρ€Π°Π· с использованиСм tr1::function:


class GameCharacter; // ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅

int defaultHealthCalc(const GameCharacter& gc); // ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅

class GameCharacter {

public:

// HealthCalcFunction – это любая вызываСмая ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΠΎΠΆΠ½ΠΎ

// ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π½Π΅Ρ‡Ρ‚ΠΎ, совмСстимоС с GameCharacter,

// ΠΈ которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅Ρ‡Ρ‚ΠΎ, совмСстимоС с int; подробности см. Π½ΠΈΠΆΠ΅

typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;

explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)

: healthFunc(hcf)

{}

int healthValue() const

{ return healthFunc(*this);}

...

private:

HealthCalcFunc healthFunc;

};


Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, HealthCalcFunc – это typedef, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ шаблона tr1::function. А Π·Π½Π°Ρ‡ΠΈΡ‚, ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΠΌ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Π΅Π΅, ΠΊΠ°ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Ρ‚ΠΈΠΏ HealthCalcFunc:


std::tr1::function<int (const GameCharacter&)>


Π—Π΄Π΅ΡΡŒ я Π²Ρ‹Π΄Π΅Π»ΠΈΠ» Β«Ρ†Π΅Π»Π΅Π²ΡƒΡŽ сигнатуру» Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ tr1::function. Π‘Π»ΠΎΠ²Π°ΠΌΠΈ Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊ: «функция, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π°Ρ ссылку Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° const GameCharacter ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ intΒ». ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° HealthCalcFunc ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡƒΡŽ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ, Ρ‡ΡŒΡ сигнатура совмСстима с Π·Π°Π΄Π°Π½Π½ΠΎΠΉ. Π‘Ρ‹Ρ‚ΡŒ совмСстимой Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΌΠΎΠΆΠ½ΠΎ нСявно ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π² const GameCharacter&, Π° Ρ‚ΠΈΠΏ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния нСявно конвСртируСтся Π² int.

Если ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠΌ Π΄ΠΈΠ·Π°ΠΉΠ½Π° (Π³Π΄Π΅ GameCharacter Π²ΠΊΠ»ΡŽΡ‡Π°Π» Π² сСбя ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ), Ρ‚ΠΎ Π²Ρ‹ Π½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚Π΅ ΠΏΠΎΡ‡Ρ‚ΠΈ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠΉ. ЕдинствСнная Ρ€Π°Π·Π½ΠΈΡ†Π° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ GameCharacter Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ содСрТит ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° tr1::function – ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π­Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎ я Π½Π°Π·Π²Π°Π» Π±Ρ‹ Π΅Π³ΠΎ нСсущСствСнным, Ссли Π±Ρ‹ Π½Π΅ Ρ‚ΠΎ ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡˆΠ΅Π»ΠΎΠΌΠ»ΡΡŽΡ‰ΡƒΡŽ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π² спСцификации Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‰ΠΈΡ… ΠΆΠΈΠ·Π½Π΅Π½Π½ΡƒΡŽ силу:


short calcHealth(const gameCharacter&); // функция вычислСния

// ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы;

// ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅ int

stuct HealthCalculator { // класс Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ…

int operator()(const GameCharacter&) const // ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‰ΠΈΡ…

{...} // ΠΆΠΈΠ·Π½Π΅Π½Π½ΡƒΡŽ силу

};

class GameLevel {

public:

float health(const GameCharacter&) const; // функция-Ρ‡Π»Π΅Π½ для

... // вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ

}; // силы; Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅ int

class EvilBadGay: public GameCharacter { // ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅

...

};

class EyeCandyCharacter: public GameCharacter { // Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ‚ΠΈΠΏ пСрсонаТСй;

... // прСдполагаСтся Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅

}; // конструктор ΠΊΠ°ΠΊ

// Ρƒ EvilBadGay

EvilBadGay ebg1(calcHealh); // пСрсонаТ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚

// Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ вычислСния

// ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы

EyeCandyCharacter ecc1(HealthCalculator()); // пСрсонаТ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚

// Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

// вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ

// силы

GameLevel currentLevel;

...

EvilBadGay ebg2( // пСрсонаТ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚

std::tr1::bind(&GameLevel::health, // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ для

currentLevel, // вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ

_1) // силы; подробности

); // см. ниТС


Π›ΠΈΡ‡Π½ΠΎ я ΠΏΠΎΡ€Π°ΠΆΠ°ΡŽΡΡŒ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊΠΈΠ΅ ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π²Π΅Ρ‰ΠΈ позволяСт Π΄Π΅Π»Π°Ρ‚ΡŒ шаблон tr1::function. Если Π²Ρ‹ Π½Π΅ раздСляСтС ΠΌΠΎΠΈΡ… чувств, Ρ‚ΠΎ Π½Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Ρ‡Ρ‚ΠΎ просто Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚Π΅, для Ρ‡Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ tr1::bind Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ebg2. ΠŸΠΎΠ·Π²ΠΎΠ»ΡŒΡ‚Π΅ ΠΌΠ½Π΅ ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ.

ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ для вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы пСрсонаТа ebg2 слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ класса GameLevel. Но ΠΈΠ· объявлСния GameLevel::health слСдуСт, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ (ссылку Π½Π° GameCharacter), Π° Π½Π° самом Π΄Π΅Π»Π΅ ΠΎΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ имССтся Π΅Ρ‰Π΅ нСявный ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° GameLevel – Ρ‚ΠΎΡ‚, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ this. ВсС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ лишь ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€: ссылку Π½Π° пСрсонаТа GameCharacter, Ρ‡ΡŒΡ ТизнСнная сила вычисляСтся. Если ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ GameLevel::health, Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Β«Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΒ» Π΅Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ вмСсто Π΄Π²ΡƒΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² (GameCharacter ΠΈ GameLevel) ΠΎΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π»Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ (GameCharacter). Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ для вычислСния Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΡ ebg2 Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ‚ΠΈΠΏΠ° GameLevel всСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ currentLevel, поэтому «привязываСм» Π΅Π³ΠΎ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ GameLevel::health. ИмСнно Π² этом ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ смысл Π²Ρ‹Π·ΠΎΠ²Π° tr1::bind: ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ функция вычислСния ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠΉ силы пСрсонаТа ebg2 Π΄ΠΎΠ»ΠΆΠ½Π° Π² качСствС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‚ΠΈΠΏΠ° GameLevel ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ currentLevel.