C ++

Як користуватися шаблонами C ++

Як користуватися шаблонами C ++

Вступ

У базовому програмуванні на C ++ тип даних, напр.g., int або char, має бути зазначено в декларації або визначенні. Таке значення, як 4 або 22 або -5, - це значення int. Таке значення, як "A", "b" або "c", є символом. Механізм шаблону дозволяє програмісту використовувати загальний тип для набору фактичних типів. Наприклад, програміст може вирішити використовувати ідентифікатор T для int або char. Можливо, щоб алгоритм С ++ мав більше одного загального типу. Скажімо, T, для int або char, U може означати тип плаваючого або вказівника. Клас, такий як рядок або векторний клас, схожий на тип даних, а екземпляри об'єктів - як значення типу даних, який є вказаним класом. Отже, механізм шаблону також дозволяє програмісту використовувати загальний ідентифікатор типу для набору класів.

Шаблон C ++ створює алгоритм, незалежний від типу використовуваних даних. Отже, один і той же алгоритм, з великою кількістю випадків одного типу, може використовувати різні типи під час різного виконання. Сутності змінної, функції, структури та класу можуть мати шаблони. У цій статті пояснюється, як оголошувати шаблони, як визначати шаблони та як застосовувати їх у C++. Ви вже повинні знати вищезазначені сутності, щоб зрозуміти теми, висвітлені в цій статті.

Типи

Скаляр

Скалярні типи - void, bool, char, int, float та pointer.

Класи як типи

Певний клас можна розглядати як тип, а його об'єкти як можливі значення.

Загальний тип представляє набір скалярних типів. Список скалярних типів великий. Наприклад, тип int має інші споріднені типи, такі як короткий int, long int тощо. Загальний тип також може представляти набір класів.

Змінна

Приклад оголошення та визначення шаблону такий:

шаблон
T pi = 3.14;

Перш ніж продовжувати, зауважте, що такий вид оператора не може відображатися у функції main () або будь-якій області блоку. Перший рядок - це декларація шаблону-голови, із вибраним програмістом загальним типовим іменем, T. Наступний рядок - це визначення ідентифікатора pi, який є загальним типом T. Точність, незалежно від того, чи T - це int, чи float, чи якийсь інший тип, може бути зроблена у функції C ++ main () (або якась інша функція). Така точність буде досягнута зі змінною pi, а не T.

Перший рядок - це оголошення шаблону-голова. Ця декларація починається із зарезервованого слова, шаблону, а потім відкритих та закритих кутових дужок. У кутових дужках є принаймні один загальний ідентифікатор типу, такий як T, вище. Може бути більше одного загального ідентифікатора типу, кожному з яких передує зарезервоване слово, typename. Такі загальні типи в цій позиції називаються параметрами шаблону.

Наступне твердження можна записати в main () або в будь-якій іншій функції:

кут << pi << '\n';

І функція відображатиме 3.14. Вираз pi визначає точний тип T для змінної pi. Спеціалізація визначає конкретний тип даних для параметра шаблону. В цьому випадку інстанціація - це внутрішній процес створення конкретного типу, наприклад float, на C ++. Не плутайте між створенням екземпляра параметра шаблону та створенням класу. У темі шаблону багато типів даних можуть мати одне загальне ім'я типу, тоді як багато класів можуть мати одне загальне ім'я класу. Однак загальне ім'я класу просто називається класом, а не як ім'я класу. Крім того, значення стосується типу даних, такого як int, як екземплярний об'єкт - до класу, наприклад класу String.

При спеціалізації обраний тип даних, такий як float, розміщується в кутових дужках після змінної. Якщо в оголошенні head-head є більше одного параметра шаблону, у виразі спеціалізації буде відповідна кількість типів даних у тому самому порядку.

При спеціалізації тип відомий як аргумент шаблону. Не плутайте між цим і аргументом функції для виклику функції.

Тип за замовчуванням

Якщо на спеціалізації не вказано жодного типу, передбачається тип за замовчуванням. Отже, з наступного виразу:

шаблон
U pi = "любов";
дисплей від:
кут << pi<> << '\n';

це "любов" до постійного вказівника на char. Зауважте в декларації, що U = const char *. Кутові дужки будуть порожніми при спеціалізації (тип не вказано); фактичний тип вважається покажчиком const на char, типовим типом. Якщо при спеціалізації потрібен був якийсь інший тип, тоді в кутових дужках було б записано назву типу. Якщо типовий тип бажаний на спеціалізації, повторення типу в кутових дужках є необов’язковим, тобто.e., кутові дужки можна залишити порожніми.

Примітка: тип за замовчуванням все ще можна змінити під час спеціалізації, встановивши інший тип.

структура

У наступному прикладі показано, як параметр шаблону можна використовувати зі структурою:

шаблон Структурні Віки

T Джон = 11;
Т Петро = 12;
Т Марія = 13;
Т Радість = 14;
;

Це вік учнів класу (класу). Перший рядок - це декларація шаблону. Тіло в брекетах - це власне визначення шаблону. Вік можна вивести у функції main () за допомогою наступного:

Віки оцінка7;
кут << grade7.John << " << grade7.Mary << '\n';

Вихід: 11 13. Перше твердження тут виконує спеціалізацію. Зверніть увагу, як це було зроблено. Це також дає назву об'єкту структури: grade7. Друге твердження має звичайні вирази об'єктних структур. Структура - це як клас. Тут Ages схоже на назву класу, тоді як grade7 є об’єктом класу (struct).

Якщо деякі віки є цілими числами, а інші - плаваючими, тоді структурі потрібні два загальних параметри, як показано нижче:

шаблон Структурні Віки

T Джон = 11;
U Петро = 12.3;
Т Марія = 13;
U Радість = 14.6;
;

Відповідний код функції main () такий:

Віки оцінка7;
кут << grade7.John << " << grade7.Peter << '\n';

Вихід: 11 12.3. При спеціалізації порядок типів (аргументів) повинен відповідати порядку загальних типів у декларації.

Декларацію шаблону можна відокремити від визначення наступним чином:

шаблон Структурні Віки

Т Джон;
У Петро;
Т Марія;
U Радість;
;
Віки клас7 = 11, 12.3, 13, 14.6;

Перший сегмент коду - це суто декларація шаблону (призначення немає). Другим сегментом коду, який є лише твердженням, є визначення ідентифікатора, grade7. Ліворуч - декларація ідентифікатора, клас 7. Правий бік - це список ініціалізатора, який присвоює відповідні значення членам структури. Другий сегмент (оператор) можна записати у функції main (), тоді як перший сегмент залишається поза функцією main ().

Нетиповий

Приклади нетипових типів включають типи int, покажчик на об'єкт, покажчик на функцію та автоматичні типи. Є й інші нетипи, на які ця стаття не звертається. Нетип - це як неповний тип, значення якого надається пізніше і не може бути змінено. Як параметр він починається з певного нетипу, за яким слідує ідентифікатор. Значення ідентифікатора надається пізніше, при спеціалізації, і не може бути змінено знову (як константа, значення якої надається пізніше). Наступна програма це ілюструє:

#включати
використання простору імен std;
шаблон Структурні Віки

T Джон = N;
U Петро = 12.3;
Т Марія = N;
U Радість = 14.6;
;
int main ()

Віки оцінка7;
кут << grade7.John << " << grade7.Joy << '\n';
повернути 0;

При спеціалізації перший тип, int, у кутових дужках є більше для офіційності, щоб переконатися, що кількість та порядок параметрів відповідає кількості та порядку типів (аргументів). Значення N було дано при спеціалізації. Вихід: 11 14.6.

Часткова спеціалізація

Припустимо, що шаблон має чотири загальних типи, і що серед чотирьох типів існує потреба у двох типах за замовчуванням. Цього можна досягти за допомогою конструкції часткової спеціалізації, в якій не використовується оператор присвоєння. Отже, конструкція часткової спеціалізації надає значення за замовчуванням підмножині загальних типів. Однак у схемі часткової спеціалізації необхідний базовий клас (struct) та частковий клас спеціалізації (struct). Наступна програма ілюструє це для одного загального типу з двох загальних типів:

#включати
використання простору імен std;
// базовий клас шаблону
шаблон
Структурні Віки

;
// часткова спеціалізація
шаблон
Структурні Віки

Т1 Джон = 11;
плавати Петро = 12.3;
Т1 Мері = 13;
float Joy = 14.6;
;
int main ()

Віки оцінка7;
кут << grade7.John << " << grade7.Joy << '\n';
повернути 0;

Визначте оголошення базового класу та його часткове визначення класу. Оголошення шаблону-голова базового класу має усі загальні параметри, необхідні. Оголошення template-head класу часткової спеціалізації має лише загальний тип. У схемі використовується додатковий набір кутових дужок, який йде відразу після назви класу у частковому визначенні спеціалізації. Це те, що насправді робить часткову спеціалізацію. Він має тип за замовчуванням і тип, який не за замовчуванням, у порядку, записаному в базовому класі. Зверніть увагу, що за замовчуванням типу все ще можна надати інший тип у функції main ().

Відповідний код у функції main () може бути таким:

Віки оцінка7;
кут << grade7.John << " << grade7.Joy << '\n';

Вихід: 11 14.6.

Пакет параметрів шаблону

Пакет параметрів - це шаблонний параметр, який приймає нульові або більше загальних типів шаблонів для відповідних типів даних. Параметр набору параметрів починається із зарезервованого слова typename або класу. Далі слідують три крапки, а потім ідентифікатор упаковки. Наступна програма ілюструє, як пакет параметрів шаблону можна використовувати зі структурою:

#включати
використання простору імен std;
шаблон Структурні Віки

int John = 11;
плавати Петро = 12.3;
int Mary = 13;
float Joy = 14.6;
;
int main ()

Віки оцінкаB;
кут << gradeB.John << " << gradeB.Mary << '\n';
Віки gradeC;
кут << gradeC.Peter << " << gradeC.Joy << '\n';
Віки оцінкаD;
кут << gradeD.John << " << gradeD.Joy << '\n';
Вік <> клас А; // як за замовчуванням
кут << gradeA.John << " << gradeA.Joy << '\n';
повернути 0;

Результат:

11 13
12.3 14.6
11 14.6
11 14.6

Шаблони функцій

Згадані вище функції шаблонів застосовуються подібним чином до шаблонів функцій. Наступна програма показує функцію з двома загальними параметрами шаблону та трьома аргументами:

#включати
використання простору імен std;
шаблон void func (T no, U cha, const char * str)

кут << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()

func (12, '$', "500");
повернути 0;

Вихід такий:

У магазині є 12 книг вартістю 500 доларів.

Відокремлення від прототипу

Визначення функції можна відокремити від прототипу, як показує наступна програма:

#включати
використання простору імен std;
шаблон void func (T no, U cha, const char * str);
шаблон void func (T no, U cha, const char * str)

кут << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()

func (12, '$', "500");
повернути 0;

Примітка: Оголошення шаблону функції не може відображатися у функції main () або будь-якій іншій функції.

Перевантаження

Перевантаження однієї і тієї ж функції може відбуватися за допомогою різних оголошень шаблону-голови. Наступна програма це ілюструє:

#включати
використання простору імен std;
шаблон void func (T no, U cha, const char * str)

кут << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

шаблон void func (T ні, const char * str)

кут << "There are " << no << " books worth $" << str << " in the store." << '\n';

int main ()

func (12, '$', "500");
func (12, "500");
повернути 0;

Результат:

У магазині є 12 книг вартістю 500 доларів.

У магазині є 12 книг вартістю 500 доларів.

Шаблони класів

Особливості згаданих вище шаблонів застосовуються подібним чином до шаблонів класів. Наступна програма - це оголошення, визначення та використання простого класу:

#включати
використання простору імен std;
клас TheCla

публічний:
int num;
статичний символ ch;
void func (char cha, const char * str)

кут << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

статична порожня забава (char ch)

якщо (ch == 'a')
кут << "Official static member function" << '\n';

;
int main ()

TheCla obj;
obj.число = 12;
obj.func ('$', "500");
повернути 0;

Вихід такий:

У магазині є 12 книг вартістю 500 доларів.

Наступна програма є наведеною вище програмою з оголошенням head-head:

#включати
використання простору імен std;
шаблон клас TheCla

публічний:
T номер;
статичний U ch;
void func (U cha, const char * str)

кут << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

статична порожня забава (U ch)

якщо (ch == 'a')
кут << "Official static member function" << '\n';

;
int main ()

TheCla obj;
obj.число = 12;
obj.func ('$', "500");
повернути 0;

Замість слова type name у списку параметрів шаблону можна використовувати слово class. Зверніть увагу на спеціалізацію в декларації об’єкта. Вихід залишається незмінним:

У магазині є 12 книг вартістю 500 доларів.

Роздільна декларація

Оголошення шаблону класу можна відокремити від коду класу наступним чином:

шаблон клас TheCla;
шаблон клас TheCla

публічний:
T номер;
статичний U ch;
void func (U cha, const char * str)

кут << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

статична порожня забава (U ch)

якщо (ch == 'a')
кут << "Official static member function" << '\n';

;

Робота зі статичними членами

Наступна програма показує, як отримати доступ до статичного члена даних та функції статичного члена:

#включати
використання простору імен std;
шаблон клас TheCla

публічний:
T номер;
статичний U ch;
void func (U cha, const char * str)

кут << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

статична порожня забава (U cha)

якщо (ch == 'a')
кут << "Official static member function" << cha << '\n';

;
шаблон U TheCla:: ch = 'a';
int main ()

TheCla:: весело ('.');
повернути 0;

Присвоєння значення статичному члену даних є декларацією і не може бути в main (). Зверніть увагу на використання та позиції загальних типів та загального типу даних у операторі присвоєння. Крім того, зауважте, що функція статичного члена даних була викликана в main () з фактичними типами даних шаблону. Результатом є наступне:

Офіційна статична функція члена.

Компіляція

Декларація (заголовок) та визначення шаблону повинні бути в одному файлі. Тобто вони повинні знаходитися в одній одиниці перекладу.

Висновок

Шаблони C ++ роблять алгоритм незалежним від типу використовуваних даних. Сутності змінної, функції, структури та класу можуть мати шаблони, що включають оголошення та визначення. Створення шаблону також передбачає спеціалізацію, тобто коли загальний тип приймає фактичний тип. Декларація та визначення шаблону повинні складатися в одній одиниці перекладу.

SuperTuxKart for Linux
SuperTuxKart is a great title designed to bring you the Mario Kart experience free of charge on your Linux system. It is pretty challenging and fun to...
Battle for Wesnoth Tutorial
The Battle for Wesnoth is one of the most popular open source strategy games that you can play at this time. Not only has this game been in developmen...
0 A.D. Tutorial
Out of the many strategy games out there, 0 A.D. manages to stand out as a comprehensive title and a very deep, tactical game despite being open sourc...