}; // ΡΠ»Π΅Π½ΠΎΠ²: 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: