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

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

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

}; // Ρ‡Π»Π΅Π½ΠΎΠ²: typename Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ


Вакая Π½Π΅ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ нСсколько Ρ€Π°Π·Π΄Ρ€Π°ΠΆΠ°Π΅Ρ‚, Π½ΠΎ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ приобрСтСния ΠΎΠΏΡ‹Ρ‚Π° Π²Ρ‹ пСрСстанСтС Π΅Π΅ Π·Π°ΠΌΠ΅Ρ‡Π°Ρ‚ΡŒ.

Рассмотрим Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования typename, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Π½Π΅Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡ‚Ρ€Π΅Ρ‚ΠΈΡ‚ΡŒ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ пишСм шаблон Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΈ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ копию – temp – ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ этот ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:


template <typename IterT>

void workWithIterator(IterT iter)

{

typename std::iterator_traits<IterT>::value_type temp(*iter);

...

}


НС ΠΏΡƒΠ³Π°ΠΉΡ‚Π΅ΡΡŒ ΠΏΡ€ΠΈ Π²ΠΈΠ΄Π΅ выраТСния std::iterator_traits<IterT>::value_type. Π—Π΄Π΅ΡΡŒ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ стандартныС классы-характСристики (traits) (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 47). Π’Π°ΠΊ, Π½Π° C++ говорят Β«Ρ‚ΠΈΠΏ Ρ‚ΠΎΠ³ΠΎ, Π½Π° Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° *IterTΒ». Π’ этом ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠΈ объявлСна локальная пСрСмСнная (temp) Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ‚ΠΈΠΏΠ°, Ρ‡Ρ‚ΠΎ ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ IterT, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ½Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ iter. Если IterT Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΈΠΏΠ° vector<int>::iterator, Ρ‚ΠΎ temp Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΈΠΏ int. Если ΠΆΠ΅ IterT Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΈΠΏΠ° vector<string>::iterator, Ρ‚ΠΎ temp Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΈΠΏ string. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ std::iterator_traits<IterT>::value_type – это Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ зависимоС имя Ρ‚ΠΈΠΏΠ° (value_type Π²Π»ΠΎΠΆΠ΅Π½ΠΎ Π²Π½ΡƒΡ‚Ρ€ΡŒ iterator_traits<IterT>, Π° IterT – ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ шаблона), ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚ΡŒ Π΅Π³ΠΎ словом typename.

Если Π²Π°ΠΌ нСприятно Π΄Π°ΠΆΠ΅ Π²ΠΈΠ΄Π΅Ρ‚ΡŒ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ std::iterator_traits<IterT>::value_type, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅, ΠΊΠ°ΠΊΠΎΠ²ΠΎ Π½Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π½Π° ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Π΅. Если Π²Ρ‹, ΠΊΠ°ΠΊ ΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ программистов, считаСтС, Ρ‡Ρ‚ΠΎ Π½Π°Π±Ρ€Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ€Π°Π·Π° нСмыслимо, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ псСвдоним для этого Ρ‚ΠΈΠΏΠ° посрСдством typedef. Для ΠΈΠΌΠ΅Π½ Ρ‡Π»Π΅Π½ΠΎΠ² классов-характСристик, ΠΊ ΠΊΠ°ΠΊΠΎΠ²Ρ‹ΠΌ относится value_type, (см. Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 47 ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ классах-характСристиках), принято соглашСниС, согласно ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ имя typedef Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π°Ρ‚ΡŒ с ΠΈΠΌΠ΅Π½Π΅ΠΌ Ρ‡Π»Π΅Π½Π°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ локального typedef ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ выглядит Ρ‚Π°ΠΊ:


template <typename IterT>

void workWithIterator(IterT iter)

{

typedef typename std::iterator_traits<IterT>::value_type value_type;

value_type temp(*iter);

...

}


ΠœΠ½ΠΎΠ³ΠΈΡ… программистов сосСдство typedef ΠΈ typename ΠΏΠΎΠ½Π°Ρ‡Π°Π»Ρƒ Ρ€Π°Π·Π΄Ρ€Π°ΠΆΠ°Π΅Ρ‚, Π½ΠΎ это логичСскоС слСдствиС ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ»Π° обращСния ΠΊ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ зависимым ΠΈΠΌΠ΅Π½Π°ΠΌ Ρ‚ΠΈΠΏΠΎΠ². Π’Ρ‹ скоро ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ½Π΅Ρ‚Π΅. К Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρƒ вас Π΅ΡΡ‚ΡŒ Π½Π° Ρ‚ΠΎ вСскиС ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹. Бколько Ρ€Π°Π· Π²Ρ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Π½Π°ΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ std::iterator_traits<IterT>::value_type?

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

Π§Ρ‚ΠΎ слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ

β€’ Π’ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½ΠΈΡΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова class ΠΈ typename взаимозамСняСмы.

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

ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ 43: НСобходимо Π·Π½Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ ΠΈΠΌΠ΅Π½Π°ΠΌ Π² ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классах

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


class CompanyA {

public:

...

void sendClearText(const std::string& msg);

void sendEncryptedText(const std::string& msg);

...

};

class CompanyB{

public:

...

void sendClearText(const std::string& msg);

void sendEncryptedText(const std::string& msg);

...

};

... // классы для Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ

class MsgInfo {...}; // класс, содСрТащий ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ,

// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ для создания

// сообщСния

template<typename Company>

class MsgSender {

public:

... // конструктор, дСструктор ΠΈ Ρ‚. ΠΏ.

void sendClear(const MsgInfo& info)

{

std::string msg;

ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ msg ΠΈΠ· info

Company c;

c.sendClearText(msg);

}

void sendSecret(const MsgInfo& info) // Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ sendClear, Π½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚

{...} // c.sendEncrypted

};


Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. Но ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠ½ΠΎΠ³Π΄Π° ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ сообщСний. Π’Π°ΠΊΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π»Π΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ, написав ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΉ класс, ΠΈ, Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд, Ρ€Π°Π·ΡƒΠΌΠ½ΠΎ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:


template <typename Company>

class LoggingMsgSender: public MsgSender<Company> {

public:

...

void sendClearMsg(const MsgInfo& info)

{

Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ;

sendClear(info); // Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса

// этот ΠΊΠΎΠ΄ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ!

Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» послС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ;

}

...

};


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ функция, ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π°Ρ сообщСниС, Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌ классС называСтся ΠΈΠ½Π°Ρ‡Π΅ (sendClearMsg), Ρ‡Π΅ΠΌ Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ (sendClear). Π­Ρ‚ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΡ‹ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ сокрытия унаслСдованных ΠΈΠΌΠ΅Π½ (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 33), Π° Ρ€Π°Π²Π½ΠΎ слоТности, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ наслСдуСмых Π½Π΅Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 36). Но этот ΠΊΠΎΠ΄ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, компилятором, совмСстимым со стандартом. Π’Π°ΠΊΠΎΠΉ компилятор Ρ€Π΅ΡˆΠΈΡ‚, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sendClear Π½Π΅ сущСствуСт. ΠœΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ эта функция ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС, Π½ΠΎ компилятор Π½Π΅ станСт ΠΈΡΠΊΠ°Ρ‚ΡŒ Π΅Π΅ Ρ‚Π°ΠΌ. ΠŸΠΎΠΏΡ‹Ρ‚Π°Π΅ΠΌΡΡ ΠΏΠΎΠ½ΡΡ‚ΡŒ – ΠΏΠΎΡ‡Π΅ΠΌΡƒ.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° компилятор встрСчаСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ шаблона класса LoggingMsgSender, ΠΎΠ½ Π½Π΅ Π·Π½Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΎΠΌΡƒ классу Ρ‚ΠΎΡ‚ наслСдуСт. ΠŸΠΎΠ½ΡΡ‚Π½ΠΎ, Ρ‡Ρ‚ΠΎ классу MsgSender<Company>, Π½ΠΎ Company – ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ шаблона, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ извСстСн Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ LoggingMsgSender. НС зная, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Company, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ выглядит класс MsgSender<Company>. Π’ частности, Π½Π΅ сущСствуСт способа ΡƒΠ·Π½Π°Ρ‚ΡŒ, Π΅ΡΡ‚ΡŒ Π»ΠΈ Π² Π½Π΅ΠΌ функция sendClear.

Π§Ρ‚ΠΎΠ±Ρ‹ яснСС ΠΏΠΎΡ‡ΡƒΠ²ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ, Π² Ρ‡Π΅ΠΌ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ, ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ класс CompanyZ, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ компанию, которая настаиваСт Π½Π° Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС сообщСния ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π»ΠΈΡΡŒ:


class CompanyZ { // этот класс Π½Π΅ прСдставляСт

public: // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sendCleartext

...

void sendEncrypted(const std::string& msg);

...

};


ΠžΠ±Ρ‰ΠΈΠΉ шаблон MsgSender Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для CompanyZ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Π½Π΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° функция sendClear, которая для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² класса CompanyZ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ MsgSender для CompanyZ:


template <> // полная спСциализация MsgSender;

class MsgSender <CompanyZ> { // отличаСтся ΠΎΡ‚ ΠΎΠ±Ρ‰Π΅Π³ΠΎ шаблона

public: // Ρ‚ΠΎΠ»ΡŒΠΊΠΎ отсутствиСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

... // sendCleartext

void sendSecret(const MsgInfo& info)

{...}

};


ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠΈΠ½Ρ‚Π°ΠΊΡΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ Β«template<>Β» Π² Π½Π°Ρ‡Π°Π»Π΅ опрСдСлСния класса. Она ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ это ΠΈ Π½Π΅ шаблон, ΠΈ Π½Π΅ Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹ΠΉ класс. Π­Ρ‚ΠΎ спСциализированная вСрсия шаблона MsgSender, которая Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ шаблона являСтся CompanyZ. НазываСтся это ΠΏΠΎΠ»Π½ΠΎΠΉ спСциализациСй шаблона : шаблон MsgSender спСциализирован для Ρ‚ΠΈΠΏΠ° CompanyZ, ΠΈ эта спСциализация примСняСтся, коль скоро Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΡƒΠΊΠ°Π·Π°Π½ Ρ‚ΠΈΠΏ CompanyZ, Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ особСнности ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона Π²ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ.

ИмСя ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ шаблона MsgSender для CompanyZ, снова рассмотрим ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΉ класс LoggingMsgSender:


template <typename Company>

class LoggingMsgSender: public MsgSender<Company> {

public:

...

void sendClearMsg(const MsgInfo& info)

{

Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ;

sendClear(info); // Ссли Company == CompanyZ,

// Ρ‚ΠΎ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ сущСствуСт

Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» послС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ;

}

...

};


Как слСдуСт ΠΈΠ· коммСнтария, этот ΠΊΠΎΠ΄ просто Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла, Ссли Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ классом являСтся MsgSender<CompanyZ>, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² Π½Π΅ΠΌ Π½Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sendClear. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ C++ ΠΎΡ‚Π²Π΅Ρ€Π³Π½Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ Π²Ρ‹Π·ΠΎΠ²; компилятор ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ шаблон Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса ΠΌΠΎΠΆΠ½ΠΎ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΈ интСрфСйс, прСдоставляСмый этой спСциализациСй, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ Ρ‚Π°ΠΊΠΈΠΌ, ΠΊΠ°ΠΊ Π² ΠΎΠ±Ρ‰Π΅ΠΌ шаблонС. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ компилятор ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅ ΠΈΡ‰Π΅Ρ‚ унаслСдованныС ΠΈΠΌΠ΅Π½Π° Π² ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классах. Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ смыслС, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΎΡ‚ Β«ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ C++Β» ΠΊ Β«C++ с шаблонами» (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 1), наслСдованиС пСрСстаСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, Π½ΡƒΠΆΠ½ΠΎ ΠΊΠ°ΠΊ-Ρ‚ΠΎ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ C++ ΠΎΡ‚ΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ Π΄ΠΎΠ³ΠΌΡ‹ Β«Π½Π΅ заглядывай Π² ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ классы». Π”ΠΎΠ±ΠΈΡ‚ΡŒΡΡ этого ΠΌΠΎΠΆΠ½ΠΎ трСмя способами. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚ΡŒ обращСния ΠΊ функциям ΠΈΠ· Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ this: