Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Лабораторная работа № 4 Тема. Шаблоны классов




Теоретическое введение. С помощью шаблонов можно создавать родовые (generic) функции и классы. Родовая функция определяет базовый набор операций, которые будут применяться к разным типам данных, получаемых функцией в качестве параметра.

Определение функции с ключевым словом template (шаблон) имеет вид:

template<class Ttype >тип имя_функции(список аргументов)

{//тело функции}

Здесь Ttype – фиктивный тип, который используется при объявлении аргументов и локальных переменных функции. Компилятор заменит этот фиктивный тип на один из реальных и создаст соответственно несколько перегружаемых функций. При этом перегружаемые функции являются ограниченными, поскольку выполняют одни и те же действия над данными различных типов.

С помощью шаблона класса можно создать класс, реализующий стек, очередь, дерево и т. д. для любых типов данных. Компилятор будет генерировать правильный тип объекта на основе типа, задаваемого при создании объекта. Общая форма объявления шаблона класса:

template <class Ttype > class имя_класса {

Имена класса, поля класса

}

Здесь Ttype – фиктивное имя типа, которое заменится компилятором на фактическое. Шаблон класса может иметь больше одного родового типа данных:

template<class Type1,class Type2> class m {Type1 a;Type2 b;}

Пример. Создается шаблон класса для работы с односвязным списком. Тестирование класса выполняется с использованием меню, которое позволяет создать список из чисел типов integer, float, double и выполнить типичные операции с ним.

#include <conio.h>

#include <string.h>

#include <iostream.h>

#include"vip\menu.cpp"

void ListForInt();

void ListForFloat();

void ListForDouble();

char bufRus[256];

char*Rus(const char*text){

CharToOem(text,bufRus);

return bufRus;

}

//шаблон класса для работы с односвязным списком

template<class mytype>class List {

//внутренний класс, для представления элементов списка

class Node{

public:

mytype d;

Node* next;

Node(mytype dat=0){d=dat; next=0;}

};

Node* pbeg; //указатель на начало списка

public:

List(){pbeg=0;} //конструктор

~List(); //деструктор

Node * Add(mytype d); //добавление в конец списка

Node * Find(mytype key); //поиск по ключу

Node * Insert(mytype key,mytype d); //вставка узла d после узла с

// ключом key

bool Remove(mytype key); //удаление узла

void Print(); //печать списка

};

//*********************~List() *************************

//ДЕСТРУКТОР. Освобождает память для всех узлов списка

template<class mytype> List<mytype>::~List(){

if(pbeg!=0){

Node* pv=pbeg;

while(pv){

pv=pv->next;

delete pbeg;

pbeg=pv;

}

}

}

//*************************** void Add(mytype d) **********

//Добавляет узел в конец списка и возвращает указатель

// на вставленный узел.

template<class mytype> List<mytype>::Node*

List<mytype>::Add(mytype d){

Node* pv=new Node(d); //Создание нового узла

if(pbeg==0)pbeg=pv; //первый узел списка

else {

Node* rab=pbeg;

while(rab!=0){

if((rab->next)==0){rab->next=pv;return pv;}

rab=rab->next;

}

}

}

//*************************** Node* Find(mytype key)

//Выполняет поиск узла с заданным ключом и возвращает указатель

// на него в случае успешного поиска и 0 в случае отсутствия узла в списке

template<class mytype> List<mytype>::Node*

List<mytype>::Find(mytype key){

Node* pv=pbeg;

while(pv){

if((pv->d)==key)break;

pv=pv->next;

}

return pv;

}

//************* Node* Insert(mytype key,mytype d)

//Вставляет в список узел после узла с ключом key и возвращает

// указатель на вставленный узел. Если такого узла в списке нет,

// вставка не выполняется и возвращается значение 0

template<class mytype> List<mytype>::Node*

List<mytype>::Insert(mytype key,mytype d){

if(Node* pkey=Find(key)) //поиск узла с ключом key

{

Node* pv=new Node(d);

//выделение памяти под новый узел и его инициализация

pv->next=pkey->next;

//установление связи нового узла с последующим

pkey->next=pv; //установление связи предыдущего узла с новым

return pv;

}

return 0;

}

//******************* bool Remove(mytype key)

//Удаляет узел с заданным ключом из списка и возвращает значение true при

//успешном удалении и false, если узел с таким ключом не найден

template<class mytype> bool List<mytype>::Remove(mytype key){

if(Node* pkey=Find(key)){

if(pkey==pbeg)pbeg=pbeg->next; //удаление из начала списка

else{ //Находим указатель на узел,

Node*rab=pbeg; //стоящий в списке перед

while(rab) //удаляемым узлом.

{ //rab-этот указатель.

if((rab->next)==pkey)break;

rab=rab->next;

}

rab->next=pkey->next;

}

delete pkey;

return true;

}

return false;

}

//******************** void Print() -Печать списка

template<class mytype> void List<mytype>::Print(){

Node*pv=pbeg;

cout<<Rus("Наш список:");cout<<endl;

while(pv){

cout<<pv->d<<' ';

pv=pv->next;

}

cout<<endl;}

//--------------------------- MAIN ---------------------------------------------

int main(int argc, char* argv[]){

int k=0,max,kol;

char menu[][100]= {{" ListForInt "}, {" ListForFloat "},

{" ListForDouble "}, {" EXIT "}, };

kol=4; //КОЛИЧЕСТВО СТРОК МЕНЮ. Это используется в выравнивании

//строк меню по центру.

//----ВЫРАВНИВАНИЕ СТРОК МЕНЮ ПО ЦЕНТРУ------------------

max=viravnivaniestrok(menu,kol);

//----------------- МЕНЮ НА ЭКРАНЕ---------------------------------------

textmode(C80);

while(1){

switch(mmm(kol,menu,max,k))

{ case 0: {

ListForInt();

k=0;break;

}

case 1: {

ListForFloat();

k=1;break;

}

case 2: {

ListForDouble();

k=2;break;

}

case 3:{

exit(0);

}

}

}

return 0;

}

//*************************** void ListForInt()

//Эта функция вызывается из главного меню.

void ListForInt(){

List<int>l1;

int k=0,max,kol;

char menu[][100]=

{ {" PrintList "}, {" Add "}, {" Find "}, {" Insert "},

{" Remove "}, {" EXIT "}, {" Back "} };

kol=7; //КОЛИЧЕСТВО СТРОК МЕНЮ.

max=viravnivaniestrok(menu,kol);

//------------------------ МЕНЮ НА ЭКРАНЕ-----------------------------

textmode(C80);

while(1){

switch(mmm(kol,menu,max,k))

{ case 0: {

l1.Print();

while(!kbhit())

k=0;break;}

case 1: {

cout<<Rus("введите число, которое надо вставить:");

int t;cin>>t;

if((l1.Add(t)))cout<<Rus("вставка осуществлена");

else cout<<Rus("вставка не осуществлена");

while(!kbhit());

k=1;break;}

case 2: {

cout<<Rus("введите искомое число:");

int t;

cin>>t;

if(l1.Find(t))cout<<Rus("искомое число есть в списке.");

else cout<<Rus("искомого числа нет в списке.");

while(!kbhit());

k=2;break;}

case 3: {

cout<<Rus("введите число, которое надо вставить:");

int t;cin>>t;

cout<<Rus("введите число, после которого надо вставить:");

int key;cin>>key;

if((l1.Insert(key,t)))cout<<Rus("вставка осуществлена");

else cout<<Rus("вставка не осуществлена");

while(!kbhit());

k=3;break;}

case 4: {

cout<<Rus("введите число, которое надо удалить:");

int t;cin>>t;

if((l1.Remove(t)))cout<<Rus("удаление осуществлено");

else cout<<Rus("такого числа нет в списке.");

while(!kbhit());

k=4;break;}

case 5:{exit(0);}

} } }

Таким же образом, как и функция ListForInt(), реализуются функции List­ForFloat() и ListForDouble(), предназначенные для тестирования списков из чисел типа float и double, соответственно.

Задания для самостоятельного решения

Для разработки шаблонов классов можно использовать результаты выполнения лабораторных работ № 2 и № 3. При тестировании со-зданных шаблонов классов необходимо создавать объекты с различными допустимыми значениями параметров шаблона (например, компоненты вектора могут быть целыми, действительными или комплексными числами).

1. Создать шаблон класса для работы со стеком. Применить его для решения задач № 1 – 4 (лаб. работа № 3).

2. Создать шаблон класса для работы с одномерным массивом. Выполнить тестирование путем создания и обработки массивов, содержащих элементы различных типов (например, сортировка элементов массивов различными методами).

3. Создать шаблон класса Vector размерности n (см. задачу № 3, лаб. работа № 2).

4. Создать шаблон класса «Квадратная матрица» – Matrix размерно­сти n´n (см. задачу № 4, лаб. работа № 2).

5. Создать шаблон класса Polynom степени n (см. задачу № 5, лаб. работа № 2) или создать шаблон класса для работы с односвязным списком. Применить его для решения задачи № 5 (лаб. работа № 3).

6. Создать шаблон класса для работы с односвязным списком. При­менить шаблон класса для решения задачи № 6 (лаб. работа № 3).

7. Создать шаблон класса для работы с односвязным списком. При­менить шаблон класса для решения задачи № 7 (лаб. работа № 3).

8. Создать шаблон класса для работы с бинарным деревом. Приме­нить его для сортировки действительных чисел и строк, вводимых с клавиатуры или из файла.

9. Создать шаблон класса Set (множество) мощности n (см. задачу № 9, лаб. работа № 2) или создать шаблон класса для работы с односвязным списком. Применить шаблон класса для решения задачи № 9 (лаб. работа № 3).

10. Создать шаблон класса для работы с односвязным списком. Применить шаблон класса для решения задачи № 10 (лаб. работа № 3).

11. Создать шаблон класса, обеспечивающего описание матрицы заданного размера n´m и любого минора в ней (см. задачу № 11, лаб. работа № 2) или создать шаблон класса для работы с двусвязным списком. Применить шаблон класса для решения задачи № 11 (лаб. работа № 3).

12. Создать шаблон класса для работы с бинарным деревом. Применить шаблон класса для решения задачи № 12 (лаб. работа № 3).

13. Создать шаблон класса для работы с бинарным деревом. Применить шаблон класса для решения задачи № 13 (лаб. работа № 3).

14. Создать шаблон класса для работы с двусвязным списком. Применить шаблон класса для решения задачи № 15 (лаб. работа № 3).

15. Создать шаблон класса для работы с односвязным списком. Применить шаблон класса для решения задачи № 16 (лаб. работа № 3).

Тесты

1. Отметьте все утверждения, которые считаете верными:

1) нельзя с помощью шаблона создать функцию с таким же име­нем, как у явно определенной функции;

2) цель введения шаблонов – создание функций, которые могут обрабаты­вать однотипные данные;

*3) при использовании шаблонов функций возможна перегрузка как с по­мощью шаблонов, так и функций;

*4) в качестве описания шаблона функции используется прото­тип шаб­лона:

2. Можно ли задать шаблон со значением параметра по умолча­нию?

Варианты ответа:

*1) да; 2) нет.

3. Каков правильный заголовок шаблона?

Варианты ответа:

*1) template<class t1,class t2>; 2) template <class t1,t2>; 3) template <class t,class t>;

4. Сколько параметров может быть у шаблона при определении шаблона функции?

Варианты ответа:

1) 1; 2) столько, сколько аргументов у функции; *3) столько, сколько типов ис­пользуется для параметризации.

5. Отметьте правильный вариант описания шаблона семейства функций:

1) template(class T)

void func(T* p1,T* p2){…}

2) template <class T>;

void func(T* p1,T* p2){…}

*3) template<class T>

void func(T* p1,T* p2){…}

4) template<class T>

void func(T* p1,T* p2){…}

6. Можно ли использовать класс-шаблон в качестве базового класса?

Варианты ответа:

*1) да; 2) нет.





Поделиться с друзьями:


Дата добавления: 2016-09-03; Мы поможем в написании ваших работ!; просмотров: 963 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Неосмысленная жизнь не стоит того, чтобы жить. © Сократ
==> читать все изречения...

2311 - | 2015 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.007 с.