68958

Узагальнені класи. Приклад використання двох узагальнених типів даних

Лекция

Информатика, кибернетика и программирование

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

Украинкский

2014-09-28

62 KB

1 чел.

Лекція № 20

Тема: Узагальнені класи

План

  1.  Узагальнені класи
  2.  Приклад використання двох узагальнених типів даних
  3.  Застосування аргументів за умовчанням в шаблонних класах
  4.  Явні спеціалізації класів

Узагальнені класи

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

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

Оголошення узагальненого класу має наступний вигляд.

template <class Ттип> class имя_класса {

}

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

Конкретний екземпляр узагальненого класу створюється за допомогою наступної синтаксичної конструкції.

имя_класса <тип> имя_объекта;

Тут параметр тип задає тип даних, якими оперує клас. Функції — члени узагальненого класу автоматично стають узагальненими. Для їх оголошення не обов'язково використовувати ключове слово template.

Наступна програма використовує узагальнений клас stack. Тепер його можна застосовувати для зберігання об'єктів будь-якого типу. У даному прикладі створюються стеки символів і дійсних чисел.

// Демонстрація узагальненого стека.

#include <iostream>

using namespace std;

const int SIZE = 10;

// Створюємо узагальнений клас stack.

template <class StackType> class stack

{

StackType stck[SIZE]; // Містить елементи стека.

int tos; // Індекс вершини стека.

public:

stack() { tos = 0;} // Ініціалізував стек.

void push(StackType ob); // Заштовхує об'єкт в стек.

StackType pop(); // Виштовхує об'єкт із стека.

};

// Заштовхуємо об'єкт в стек.

template <class StackType> void stack<StackType>::push(StackType ob)

{

if(tos==SIZE){

cout << "Стек повний.\ п";

return;

}

stck[tos]= ob;

tos++;

}

// Виштовхуємо об'єкт із стека.

template <Class StackType> StackType stack<StackType>::pop()

{

if(tos==0){

cout << "Стек порожній..\n";

return 0; // Якщо стек порожній, повертається константа null.

}

tos--;

return stck[tos];

}

int main()

{

// Демонстрація стека символів.

stack<char> s1, s2; // Створюємо два стеки символів.

int i ;

s1.push ('a'); s2.push('x') s1.push('b' ); s2.push('y');

s1.push('c'); s2.push(' z' );

 for(i=0; i<3; i++) cout << "Виштовхуємо s1: “ « s1.pop() « '\n';

for(i=0; i<3; i++) cout << "Виштовхуємо s2: “ « s2.pop() « '\n';

// Демонстрація стека дійсних чисел

stack<double> dsl, ds2; // Створюємо два стеки дійсних чисел.

dsl.push(1.1); ds2.push(2.2); dsl.push(3.3); ds2.push(4.4);

dsl.push(5.5); ds2.push(6.6);

for(i=0; i<3; i++) cout « "Виштовхуємо dsl: " « dsl.pop() « "\n";

for(i=0; i<3; i++) cout « "Виштовхуємо ds2: " « ds2.pop() « "\n";

return 0;

}

Як видимий, оголошення узагальненого класу мало відрізняється від оголошення узагальненій функції. Фактичний тип даних, що розміщується в стеку, в оголошенні класу замінюється узагальненим параметром і уточнюється лише при створенні конкретного об'єкту. При оголошенні конкретного об'єкту класу stack компілятор автоматично генерує всі функції і змінні, необхідні для обробки фактичних даних. У попередньому прикладі оголошуються по два стеки різних типів — цілих чисел і дійсних чисел. Зверніть особливу увагу на наступні оголошення.

stack<char> s1, s2; // Створюємо два стеки символів.

stack<double> dsl, ds2; // Створюємо два стеки дійсних чисел.

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

stack<char *> chrptrQ;

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

struct addr {

char name[40];

char street[40];

char city[30];

char state[3];

char zip[12];

};

В цьому випадку клас stack породжує стек, в якому зберігаються об'єкти класу addr Для цього використовується наступне оголошення.

stack<addr> obj;

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

Приклад використання двох узагальнених типів даних

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

 

/* Приклад класу, що використовує два узагальнені типи. */

#include <iostream>

using namespace std;

template <class Typel, class Type2> class myclass

{

Typel i;

Type2 j;

public:

myclass(Typel а, Type2 b) { i = а; j = b; }

void show() { cout « i « ' ' « j « '\n'; }

};

int main()

{

myclass<int, double> ob1(10, 0.23);

myclass<char, char *> ob2('X', "Шаблони — могутній механізм.");

obl.show(); // Виводиться ціле і дійсне число.

ob2.show(); // Виводиться символ і покажчик на символ.

return 0;

}

Ця програма виводить наступні результати.

10 0.23

X Шаблони — могутній механізм.

У програмі оголошуються об'єкти двох типів. Об'єкт obl використовує цілі і дійсні числа. Об'єкт ob2 використовує символ і покажчик на символ. У обох випадках при створенні об'єктів компілятор автоматично генерує відповідні дані і функції.

Застосування аргументів за умовчанням в шаблонних класах

Шаблонний клас може мати аргумент узагальненого типу, значення якого задане за умовчанням. Наприклад, такий.

template <Class X=int> class myclass { //...

Якщо при конкретизації об'єкту типу myclass не буде вказаний жоден тип, використовується тип int.

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

Розглянемо ще один варіант безпечного масиву, що передбачає аргументи за умовчанням як для типу даних, так і для розміру масиву.

// Демонстрація шаблонних аргументів за умовчанням.

#include <iostream>

#include <cstdlib>

using namespace std;

// Параметр типу Атуре за умовчанням рівний int,

// а змінна size за умовчанням рівна 10.

template <class AType=int, int size=10> class atype {

AType а[size]; // Розмір масиву передається аргументом size.

public:

atype() {

register int i;

for(i=0; i<size; i++) а[i]= i;

}

AType &operator[](int i); };

// Перевірка діапазону для об'єкту atype.

template<class AType,int size> AType &atype<AType,size>::operator[](int i){

if(i<0 || i> size-1){

cout « "\nЗначение індексу ";

cout « i « " виходить за межі допустимого даипаэона.\n";

exit(l);

}

return а[i];

}

int main()

{

atype<int, 100> intarray; // Цілочисельний масив з 100 елементів.

atype<double> doublearray; // Масив дійсних чисел 

//розмір заданий за умовчанням.

atypeo defarray; //За умовчанням оголошується цілочисельний

// масив, що складається з 10 елементів.

int i ;

cout « "Цілочисельний масив: ";

for(i=0; i<100; i++) intarray[i]= i;

for(i=0; i<100; i++) cout « intarray[i]« " ";

cout « '\n' ;

cout « "Масив дійсних чисел: ";

for(i=0; i<10; i++) doublearray[i]= (double) i/3;

for(i=0; i<10; i++) cout « doublearray[i] << " ";

cout « ' \n' ;

cout << "Масив за умовчанням: ";

for(i=0; i<10; i++) defarray [i] = i;

for(i=0; i<10; i++) cout « defarray[i]« " ";

cout << '\n';

return 0;

}

Зверніть увагу на рядок

template <class AType=int, int size=10> class atype {

Тут тип АTуре за умовчанням є типом int, а змінна size рівна 10. Як демонструє програма, об'єкти класу atype можна створити трьома способами.

• Явно задаючи тип і розмір масиву.

• Явно задаючи тип масиву, використовуючи розмір за умовчанням.

• Використовуючи тип і розмір масиву, встановлені за умовчанням.

Застосування аргументів за умовчанням (особливо типів) підвищує універсальність шаблонних класів. Якщо якийсь тип використовується частішим за інших, його можна задати за умовчанням, надавши користувачеві самому конкретизувати інші типи.

Явні спеціалізації класів

Як і при використанні шаблонних функцій, можна створити явну спеціалізацію узагальненого класу. Для цього, як і раніше, застосовується конструкція taraplate<>.

// Демонстрація спеціалізації класу.

#include <iostream>

using namespace std;

template <class T> class myclass {

T x;

public:

myclass(T а){

cout « "Усередині узагальненого класу myclass\n";

x = а;

}

T getx() { return x; }

};

// Явна спеціалізація для типу int.

template<> class myclass<int> {

int x;

public:

myclass(int а){

cout « "Усередині спеціалізації myclass<int>\n";

x = а * а;

}

int getx() { return x; }

};

int main() {

myclass<double> d(10.1);

cout « "double: " « d.getx() « "\n\n";

myclass<int> i(5);

cout « "int: " « i.getx() « "\n";

return 0;

}

Програма виводить на екран наступні результати.

Усередині узагальненого класу myclass

double: 10.1

Зверніть увагу на наступний рядок програми.

template <> class myclass<int> {

Вона повідомляє компілятор, що створюється явна цілочисельна спеціалізація узагальненого класу myclass. Така ж синтаксична конструкція застосовується для будь-якої іншої спеціалізації класу.

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


 

А также другие работы, которые могут Вас заинтересовать

47353. Проектирование заготовки 108.5 KB
  Определить вид заготовки, используемый для изготовления данной детали; определение метода получения заготовки; является функцией специалиста – технолога литейщика или давленца; Наметить расположение плоскости разъема; которое определяет распределение напусков, формовочных, штамповочных уклонов;
47354. Фільтрація та консолідація даних в середовищі MS Excel 319.52 KB
  Пошук та фільтрація – це операції, які найчастіше виконуються над базами даних (списками). Для цього програмою MS Excel надається набір засобів.
47355. Аналіз даних в середовищі MS Excel 110.18 KB
  Ознайомити з засобами аналізу даних в середовищі MS Excel, можливостями аналізу за допомогою функцій і таблиць підстановок; набути навичок проведення аналізу за допомогою зведених таблиць...
47356. ІСТОРІЯ ШОРТ, ТА ЇХ ДЕТАЛЬНЕ СТВОРЕННЯ 981.49 KB
  Як тлумачить словник, шортами називаються укорочені брюки зручні для літнього відпочинку. Шорти старше брюк! Вже так повелося, що спочатку всі люди ходили в спідницях. Потім до стародавніх дизайнерів прийшла думка зробити розріз посередині і зшити частини тканини. Так спідниця перестала обмежувати ноги при ходьбі. Але це ще не були шорти. Історія походження шорт тільки починалася.
47358. Общественные отношения, возникающие в связи определением организации адвокатуры России и некоторых зарубежных странах 333.5 KB
  В последние годы в нашей стране активно формируется рынок предоставления квалифицированной правовой помощи. Однако того количества профессиональных юристов, которое действует сегодня на территории Российской Федерации, явно недостаточно для обеспечения граждан и организаций юридической помощью.
47359. ЦИКЛ ТЕПЛОВОГО НАСОСА 650 KB
  Изучение цикла теплового насоса. Определение отопительного коэффициента (коэффициента преобразования) теплового насоса. Определение количества низкопотенциальной теплоты, отбираемой у окружающей среды. Определение количества теплоты, передаваемой в систему отопления помещения.
47361. Социально-психологические методы управления коллективом 243 KB
  Под социально-психологическими методами управления понимают конкретные приемы и способы воздействия на процесс формирования и развития самого коллектива и отдельных работников. Разделяют два метода: социальные (направленные на коллектив в целом), и психологические (направленные на отдельные личности внутри коллектива). Эти методы подразумевают внедрение различных социологических и психологических процедур в практику управления