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. Така ж синтаксична конструкція застосовується для будь-якої іншої спеціалізації класу.

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


 

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

42879. Создания простейшей экспертной системы 69.17 KB
  Если реакция системы не понятна пользователю то он может потребовать объяснения: CLIPS Первоначально аббревиатура CLIPS была названием языка С Lnguge Integrted Production System язык С интегрированный с продукционными системами удобного для разработки баз знаний и макетов экспертных систем. Теперь CLIPS представляет собой современный инструмент предназначенный для создания экспертных систем expert system tool. CLIPS состоит из интерактивной среды экспертной оболочки со своим способом представления знаний гибкого и мощного...
42880. Состояния международного туризма на современном этапе 84.24 KB
  Туризм – явление, известное каждому. Во все времена нашу планету пересекали многочисленные путешественники и первопроходцы. Но лишь недавно туризм возник как специфическая форма деятельности людей. Каждый из нас представляет себе туризм как отрасль, более или менее известную, поскольку все мы куда-то ездили и проводили отпуска вдали от дома. Туризм - сравнительно молодой феномен, имеющий, однако, корни, уходящие в древние времена.
42881. Поняття туризму. Класифікація, види і форми туризму 59.48 KB
  Термін туризм (tourism) першим вжив В. Жекмо в 1830 р. Слово «туризм» походить від французького «tour», що означає «прогулянка». До недавнього часу в різних країнах поняття «туризм», «турист» розумілися неоднаково. З розвитком туризму в сучасному світі, особливо міжнародного і з створенням міжнародних туристичних організацій, стало необхідним дати загальноприйняте визначення поняття «турист» і відповідно «туризм».
42882. SMS-Flooder 284.94 KB
  При атаках автоматизированных систем достаточно сложно определить предсказать уровень ущерба и риска который они могут предоставить. На основе вышеизложенного рассмотрим момент риска по формуле: Отсюда среднее значение ущерба для кривой риска будет равно Далее получим центральный момент риска: Откуда мы можем выразить второй центральный момент риска: Тогда среднеквадратичное отклонение будет иметь вид: Также оно может быть найдено относительно моды риска . Она может выражаться через решение следующего уравнения: Чтобы оценить ассиметрию...
42883. Химическая металлизация печатных плат 1.32 MB
  И так как вытравливается только этот минимальный слой около 3 мкм то величина подтравов минимальна до 2 мкм что позволяет воспроизводить проводники малой ширины. Поэтому в методе необходимо применять фоторезист толщиной около 30 мкм. Затяжкой Тентинг –метод с общей металлизацией поверхности заготовки Слои 1 2 3 4 5 18 мкм 18 мкм 18 мкм Фольга 3 мкм 6 мкм 35 мкм Общая металлизация поверхности 30 мкм 40 мкм 40 мкм 50 мкм Фоторезист 25 мкм 35 мкм 35 мкм Металлизация рисунка 15 мкм 15 мкм Металлорезист 3 мкм 18 мкм 24 мкм 53 мкм Глубина...
42884. Разработка программы для построения графика временной функции в реальном и машинном времени 439 KB
  Создание MS-DOS QuickBASIC (сокращенное обозначение – QB) в середине 80-х годов произвело настоящую революцию в мире BASIC, результатом которой было то, что впервые этот язык занял достаточно прочные позиции среди средств разработки серьезных прикладных систем. В QuickBASIC в достаточно полной мере реализованы идеи структурного и модульного программирования, возможности использования процедур и функций.
42885. Разработка обучающей программы по планированию перемещения артиллерии при заданных рубежах: готовности; начала перемещения; выхода в атаку 247.06 KB
  После запуска следует выбрать какие рубежи заданы Для примера в варианте расчета при заданном рубеже начала перемещения дана схема отображающая перемещения войск в зависимости от введенных данных.
42886. Поиск и индексация в Web. Интернет-каталоги 1004 KB
  Помимо глобального поиска в пространстве Интернет существует также проблема локального поиска, т.е. поиска в пределах одного сайта или портала. Существуют готовые решения, однако для поиска внутри сайта иногда требуется более точная настройка и свои, индивидуальные, алгоритмы, которые будут осуществлять более точный и быстрый поиск по тем данным, с которыми работает сайт. Одним из главных недостатком стандартных решений от Google или Яндекс, например, также является низкая скорость обновления информации о страницах, т.е. индексации.