Студопедия
Новини освіти і науки:
МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах


РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання


ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ"


ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ


Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків


Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні


Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах


Гендерна антидискримінаційна експертиза може зробити нас моральними рабами


ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ


ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів



Використання шаблонів

Визначення функцій-членів шаблона класу

Оголошення шаблону класів та визначення його методів

Окрім шаблонів функцій, можна оголошувати і шаблони класів.

Шаблон класу є узагальненим визначенням класу, що включає типи даних як параметри, з якого компілятор автоматично створює клас для заданих користувачем типів даних. Коли компілятор створює за шаблоном класу конкретний клас для певних користувачем типів даних, то говорять, що він створив породжений клас. У зв’язку з цією обставиною шаблон класу називають іноді родовим класом. Синтаксис оголошення шаблона класу має наступний вигляд:

template <class T1 ідентифікатор1, T2 ідентифікатор2,..., TN ідентифікаторN>

class ім’я класу

{

//тіло класу

}

За ключовим словом template записують один або декілька параметрів, вкладених в кутові дужки, розділені між собою комами. Кожний параметр є:

· або ключовим словом class, за яким записують ім’я типу;

· або ім’ям типа, за яким записують ідентифікатор.

Потім іде оголошення класу. Оголошення і визначення класу використовують список параметрів шаблона. Для завдання типів даних, що параметризуються, замість ключового слова class в кутових дужках може також використовуватися ключове слово typename. Як і у разі шаблонних функцій, ключове слово class або typename показує, що параметр представляє або вбудований, або визначений користувачем тип даних. Параметри шаблона, наступні за ключовим словом class або typename, називають типами, що параметризуються. Параметри шаблона, що складаються з імені типу і наступного за ним ідентифікатора, інформують компілятор про те, що параметром шаблона є константа вказаного типу. У зв’язку з цим такі параметри називаються нетиповими. Ім’я формального параметра в списку параметрів шаблона класу повинне бути унікальним.

 

Функції-члени шаблона класу можуть визначатися в тілі класу (тобто як вбудовані) або зовні тіла класу. В останньому випадку її визначення має вигляд:

template <class T1 ідентифікатор1,

T2 ідентифікатор2,...,

TN ідентифікаторN>

тип ім’я класу

template <class T1 ідентифікатор1,

T2 ідентифікатор2,...,

TN ідентифікаторN>

:: ім’я функції (список параметрів)

{

//Тіло функції

}

 

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

template <class T>

class vector

{

public:

vector():nitem(0),items(0){};

~vector () {delete items;};

void insert (const T& t)

{ T* tmp = items;

items = new T[nitem + 1];

memcpy (items, tmp, sizeof(T) *nitem);

item[++nitem] = t;

delete tmp; }

void remove (void)

{ T * tmp = items;

items = new T [ --nitem];

memcpy (items, tmp, sizeof (T) *nitem);

delete tmp;

}

const T& operator [] (int index) const

{

if ((index < 0) || (index >= nitem))

throw IndexOutOfRange;

return items[index];

}

T& operator[](int index)

{

if ((index < 0) || (index >= nitem))

throw IndexOutOfRange;

return items[index];

}

private:

Т* items;

int nitem;

};

Окрім конструктора і деструктора у нашого вектора є тільки три методи: метод insert додає в кінець вектора новий елемент, збільшуючи довжину вектора на одиницю, метод remove видаляє останній елемент вектора, зменшуючи його довжину на одиницю, і операція [.] звертається до n-ому елемента вектора.

Параметр шаблона vector - будь-який тип, у якого визначені операція привласнення і стандартний конструктор. Згенерувати конкретний клас з шаблона можна явно, записавши:

template vector<int>;

Цей оператор не створить ніяких об'єктів типу vector<int> але проте викличе генерацію класу зі всіма його методами.

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

template <class T>

void sort_vector(vector<T>& vec)

{

for (int i = 0; i < vec.size() -1; i++)

for (int j = i; j < vec.size(); j++) {

if (vec[i] < vec[j]) {

Т tmp = vec[i];

vec[i]= vec[j];

vec[j]= tmp;

}

}

}

Ця функція працюватиме добре з числами, але якщо ми схочемо її використовувати для масиву вказівників на рядки (char*), то результат буде не зовсім очікуваний. Сортування відбудеться не по значенню рядків, а за їх адресами (операція менше для двох вказівників -це порівняння значень цих вказівників, тобто адрес величин, на які вони вказують, а не самих величин). Щоб виправити недолік, додамо другий параметр до шаблону:

template <class Т, class Compare>

void sort__vector (vector<T>& vec)

{

for (int i = 0; i < vec.size() - 1; i++)

for (int j = i; j < vec.size(); j++) {

if (Compare:: less (vec [i], vec[j])){

Т tmp = vec [i];

vec [i] = vec[ j ];

vec[j]= tmp;

}

}

}

Клас Compare повинен реалізовувати статичну функцію less, що порівнює два значення типу T. Для цілих чисел цей клас може виглядати таким чином:

class Comparelnt

static bool less(int а, int b) { return а < b; };

і сортування вектора буде мати вигляд

vector<int> vec;

sort<int, Compareint>(vec);

Для вказівників на байт (рядків) можна створити клас class CompareCharStr

static bool less(char* а, char* b)

{ return strcmp(а,b) >= 0); };

і, відповідно, сортувати за допомогою виклику

vector<char*> svec;

sort<char*, CompareCharStr>(svec);

Як легко помітити, для всіх типів, для яких операція менше має потрібний нам сенс, можна написати шаблон класу порівняння:

template<class T> Compare

static bool less (Т а, T b) { return а < b; };

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

vector<double> dvec;

sort<double, Compare<double> >(dvec);

Щоб не захаращувати запис, скористаємося можливістю задання значення параметра за замовчуванням. Так само, як і для аргументів функцій і методів, для параметрів шаблона можна визначити значення за замовчуванням. Остаточний вид функції сортування буде наступний:

template <class Т, class C = Compare<T> >

void sort_vector(vector<T>& vec)

{

for (int i = 0; i < vec.size() - 1; i++)

for (int j = i; j < vec.size (); j++) {

if (C::less(vec[i], vec[j])) {

Т tmp = vec[i];

vec[i]= vec[j];

vec [ j] = tmp;

}

}

}

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

 


Читайте також:

  1. А. Розрахунки з використанням дистанційного банкінгу.
  2. Альтернативна вартість та її використання у проектному аналізі
  3. Аналіз використання капіталу.
  4. Аналіз використання матеріальних ресурсів
  5. Аналіз використання матеріальних ресурсів.
  6. Аналіз використання обладнання.
  7. Аналіз використання прибутку та резервів його зростання
  8. Аналіз використання робочого часу на підприємстві
  9. Аналіз використання фонду робочого часу.
  10. Аналіз ефективності використання каналів розподілу
  11. Аналіз ефективності використання оборотних активів
  12. Аналіз ефективності використання основних засобів.




Переглядів: 915

<== попередня сторінка | наступна сторінка ==>
Перше звернення до функції max генерує функцію | 

Не знайшли потрібну інформацію? Скористайтесь пошуком google:

  

© studopedia.com.ua При використанні або копіюванні матеріалів пряме посилання на сайт обов'язкове.


Генерація сторінки за: 0.142 сек.