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

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

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

template<typename T, typename N = short>

Как ΠΈ Π² случаС с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΏΡ€ΠΈ условии, Ρ‡Ρ‚ΠΎ этот послСдний ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΈΠ»ΠΈ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ справа ΠΎΡ‚ Π½Π΅Π³ΠΎ ΠΈΠΌΠ΅ΡŽΡ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 8.12 ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ шаблона даСтся Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ мСстС, Ρ‡Ρ‚ΠΎ ΠΈ Π΅Π³ΠΎ объявлСниС. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ это дСлаСтся для экономии мСста, Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ, Π½Π΅ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π΅ΡΡ‚ΡŒ ΠΈ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°. Π¨Π°Π±Π»ΠΎΠ½Ρ‹ (классов ΠΈΠ»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ β€” см. Ρ€Π΅Ρ†Π΅ΠΏΡ‚ 8.12) ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Π΄Π²ΠΎΠΈΡ‡Π½ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° создаСтся ΠΈΡ… экзСмпляр. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ объявлСниС шаблона Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅, Π° Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ β€” Π² исходном Ρ„Π°ΠΉΠ»Π΅ (Ρ‚.Π΅. .cpp) ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π² Π½Π΅ΠΌ Π½Π΅Ρ‡Π΅Π³ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ! Из этого ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, Π½ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΡ€ΠΈ написании шаблона класса Π΅Π³ΠΎ рСализация Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠΎΠΌΠ΅ΡˆΠ°Ρ‚ΡŒΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΈΠ»ΠΈ встраиваСмом Ρ„Π°ΠΉΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌ.

Π’ этом случаС трСбуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСсколько Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ синтаксис. ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ части класса ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ классС, Π½ΠΎ ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² трСбуСтся Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ лСксСмы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ говорят компилятору, Ρ‡Ρ‚ΠΎ это части шаблона класса. НапримСр, getVal ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π²ΠΎΡ‚ Ρ‚Π°ΠΊ (сравнитС с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ 8.12)

template<typename T>

const T& TreeNode<T>::getVal() const {

 return(val_);

}

Π’Π΅Π»ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ выглядит Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅.

Однако с шаблонами слСдуСт Π±Ρ‹Ρ‚ΡŒ остороТными, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ссли Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ шаблон, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ повсСмСстно, Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π°Π·Π΄ΡƒΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°, Ρ‡Ρ‚ΠΎ случаСтся, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ шаблон с ΠΎΠ΄Π½ΠΈΠΌΠΈ ΠΈ Ρ‚Π΅ΠΌΠΈ ΠΆΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, TreeNode<int, short>) компилируСтся Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»Π°Ρ…. По сущСству Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°ΠΉΠ»Π°Ρ… окаТСтся ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ прСдставлСниС экзСмпляра шаблона, ΠΈ это сдСлаСт Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΈΠ»ΠΈ исполняСмый Ρ„Π°ΠΉΠ» Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ большС ΠΏΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ, Ρ‡Π΅ΠΌ трСбуСтся.

Одним ΠΈΠ· способов ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этого являСтся использованиС явного создания экзСмпляров, Ρ‡Ρ‚ΠΎ позволяСт ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ компилятору ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ шаблона класса для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡ€Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона. Если ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это Π² Ρ‚Π°ΠΊΠΎΠΌ мСстС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ компонуСтся вмСстС с ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ клиСнтскими частями, Ρ‚ΠΎ раздувания ΠΊΠΎΠ΄Π° Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚. НапримСр, Ссли извСстно, Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ TreeNode<string>, Ρ‚ΠΎ Π² ΠΎΠ±Ρ‰ΠΈΠΉ исходный Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ строку.

// common.cpp

template class TreeNode<string>;

Π‘ΠΎΠ±Π΅Ρ€ΠΈΡ‚Π΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ с этим Ρ„Π°ΠΉΠ»ΠΎΠΌ, ΠΈ послС этого ΠΊΠΎΠ΄, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ TreeNode<string>, смоТСт ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ эту Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ динамичСски, Π½Π΅ содСрТа своСй собствСнной скомпилированной вСрсии шаблона. Π”Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» шаблона класса, Π·Π°Ρ‚Π΅ΠΌ ΡΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Π°Ρ‚ΡŒΡΡ с этой Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ ΠΈ. ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ нСобходимости ΠΈΠΌΠ΅Ρ‚ΡŒ свою копию. Однако этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ провСдСния экспСримСнтов, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ всС компиляторы ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с Ρ€Π°Π·Π΄ΡƒΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π°, Π½ΠΎ это ΠΎΠ±Ρ‰ΠΈΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ для Π΅Π³ΠΎ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ.

Π¨Π°Π±Π»ΠΎΠ½Ρ‹ C++ (ΠΊΠ°ΠΊ классов, Ρ‚Π°ΠΊ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ) β€” это ΠΎΡ‡Π΅Π½ΡŒ ΠΎΠ±ΡˆΠΈΡ€Π½Π°Ρ Ρ‚Π΅ΠΌΠ°, ΠΈ имССтся ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ количСство ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊ создания ΠΌΠΎΡ‰Π½Ρ‹Ρ…, эффСктивных ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² Π½Π° основС шаблонов. Π’Π΅Π»ΠΈΠΊΠΎΠ»Π΅ΠΏΠ½Ρ‹ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ шаблонов классов ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹ ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ vector, list, set ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π³Π»Π°Π²Π΅ 15. Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ интСрСсных Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΎΠΊ, описанных Π² Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Π΅ ΠΏΠΎ Π‘++, связана с шаблонами. Если Π²Ρ‹ Π·Π°ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Π»ΠΈΡΡŒ этим ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΎΠΌ, ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ Π³Ρ€ΡƒΠΏΠΏΡ‹ новостСй comp.lang.std.c++ ΠΈ comp.lang.c++. Π’ Π½ΠΈΡ… всСгда ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ интСрСсныС вопросы ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹ Π½Π° Π½ΠΈΡ….

Π‘ΠΌΠΎΡ‚Ρ€ΠΈ Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚ 8.12.

8.12. НаписаниС шаблона ΠΌΠ΅Ρ‚ΠΎΠ΄Π° класса

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

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ любого Ρ‚ΠΈΠΏΠ°, ΠΈ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒΡΡ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ ΠΎΠ΄Π½ΠΈΠΌ Ρ‚ΠΈΠΏΠΎΠΌ ΠΈΠ»ΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ Ρ‚ΠΈΠΏΠΎΠ² (ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс).

РСшСниС

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ шаблон ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ шаблона для Ρ‚ΠΈΠΏΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. НСбольшая ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΡ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 8.13.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 8.13. ИспользованиС шаблона ΠΌΠ΅Ρ‚ΠΎΠ΄Π°

class ObjectManager {

public:

 template<typename T> T* gimmeAnObject();

 template<typename T>

 void gimmeAnObject(T*& p);

};


template<typename T>

T* ObjectManager::gimmeAnObject() {

 return(new T);

}


template<typename T>

void ObjectManager::gimmeAnObject(T*& p) {

 p = new T;

}


class X { /*...*/ };


class Y { /* ... */ };


int main() {

 ObjectManager om;

 X* p1 = om.gimmeAnObject<X>(); // ВрСбуСтся ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€

 Y* p2 = om.gimmeAnObject<Y>(); // шаблона

 om.gimmeAnObject(p1); // Однако Π½Π΅ здСсь, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ компилятор ΠΌΠΎΠΆΠ΅Ρ‚

 om.gimmeAnObject(p2); // Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ ΠΎ Ρ‚ΠΈΠΏΠ΅ T ΠΏΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌ

}

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

ΠŸΡ€ΠΈ обсуТдСнии шаблонов Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠ»ΠΈ классов слова Β«ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Β» ΠΈ Β«Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Β» становятся нСсколько двусмыслСнными. Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ ΠΏΠΎ Π΄Π²Π° Π²ΠΈΠ΄Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ: шаблона ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона β€” это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² ΡƒΠ³Π»ΠΎΠ²Ρ‹Ρ… скобках, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ T Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 8.13, Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ β€” это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ смыслС.

Рассмотрим класс ObjectManager ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 8.13. Π­Ρ‚ΠΎ упрощСнная вСрсия шаблона Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ, описанного Π² Ρ€Π΅Ρ†Π΅ΠΏΡ‚Π΅ 8.2, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΠ½Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΎΡΡŒ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ gimmeAnObject, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСт Π½ΠΎΠ²Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ клиСнтский ΠΊΠΎΠ΄ смоТСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ вмСсто нСпосрСдствСнного обращСния ΠΊ new. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, Π»ΠΈΠ±ΠΎ возвращая ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π»ΠΈΠ±ΠΎ измСняя ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ клиСнтским ΠΊΠΎΠ΄ΠΎΠΌ. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· этих ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ².

ОбъявлСниС шаблона ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ использовано ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово template ΠΈ Π±Ρ‹Π»ΠΈ ΡƒΠΊΠ°Π·Π°Π½Ρ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона.

template<typename T> T* gimmeAnObject();

template<typename T> void gimmeAnObject(T*& p);

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

template<typename T>

T* ObjectManager.:gimmeAnObject() {

 return(new T);

}


template<typename T>

void ObjectManager::gimmeAnObject(T*& p) {

 p = new T;

}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΅ΡΡ‚ΡŒ ΠΏΠ°Ρ€Π° способов Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ эти ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ². Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ явно, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона, ΠΊΠ°ΠΊ здСсь.

X* p1 = om.gimmeAnObject<X>();

X β€” это имя Π½Π΅ΠΊΠΎΠ΅Π³ΠΎ класса. Π›ΠΈΠ±ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ компилятору Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ ΠΎΠ± Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона, ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ‚ΠΈΠΏΠ° (Ρ‚ΠΈΠΏΠΎΠ²) ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π²Ρ‚ΠΎΡ€ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ gimmeAnObject, Π½Π΅ пСрСдавая Π΅ΠΉ Π½ΠΈΡ‡Π΅Π³ΠΎ Π² ΡƒΠ³Π»ΠΎΠ²Ρ‹Ρ… скобках.

om.gimmeAnObject(p1);

Π­Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ благодаря Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ компилятор ΠΌΠΎΠΆΠ΅Ρ‚ Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ ΠΎ T, посмотрСв Π½Π° p1 ΠΈ распознав, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ X*. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для шаблонов Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈΠ»ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ…) ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона понятны ΠΈΠ· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ большой популярности ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π½Π° C++, Π½ΠΎ врСмя ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΎΠ½ΠΈ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ слСдуСт Π·Π½Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈΡ…. Π― часто ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°ΡŽΡΡŒ с Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ ΡΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ сСбя, ΠΊΠΎΠ³Π΄Π° ΠΌΠ½Π΅ хочСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π» с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ связаны Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ наслСдования. НапримСр, Ссли Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ foo, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ всСгда Π±ΡƒΠ΄Π΅Ρ‚ классом, наслСдуСмым ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса, Ρ‚ΠΎ шаблон Π½Π΅ трСбуСтся: здСсь ΠΌΠΎΠΆΠ½ΠΎ просто ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса ΠΈΠ»ΠΈ ссылки. ПослС этого этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ прСкрасно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΌ Ρ‚ΠΈΠΏ любого подкласса; это обСспСчиваСтся самим C++.

Но ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ функция, которая Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ΡΡ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса (ΠΈΠ»ΠΈ классов). Π’ этом случаС ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈΠ±ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ нСсколько Ρ€Π°Π· ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ β€” ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Ρ€Π°Π·Ρƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Ρ‚ΠΈΠΏΠΎΠ², Π»ΠΈΠ±ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ шаблоном ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. ИспользованиС шаблонов Ρ‚Π°ΠΊΠΆΠ΅ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ шаблонов для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона. Но это Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π° Ρ€Π°ΠΌΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ€Π΅Ρ†Π΅ΠΏΡ‚Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ сСйчас я ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π°ΡŽ обсуТдСниС, Π½ΠΎ это мощная ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ°, поэтому ΠΏΡ€ΠΈ использовании программирования шаблонов Π½Π΅ Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΏΡ€ΠΎ Ρ‚Π°ΠΊΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ.

Π‘ΠΌΠΎΡ‚Ρ€ΠΈ Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚ 8.11.

8.13. ΠŸΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°

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

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ класс, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΈΠΌΠ΅ΡŽΡ‚ смысл ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°, ΠΈ трСбуСтся ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ operator++ ΠΈ operator--, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ позволят Π»Π΅Π³ΠΊΠΎ ΠΈ ΠΈΠ½Ρ‚ΡƒΠΈΡ‚ΠΈΠ²Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ ΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² этого класса.