
Lecture-OOP-11-Template.ppt
- Количество слайдов: 19
Шаблоны template Доц. Скакун С. В. 1
Шаблонные классы Класс, в котором определены все необходимые алгоритмы, а фактические типы обрабатываемых данных задаются в качестве параметров позже, при создании объектов этого класса (динамически) Позволяет применять один и тот же код к разным типам, причем тип является параметром тела кода 2
Применение Шаблонные классы полезны, когда класс содержит общую логику работы Пример n n алгоритм, который реализует очередь целых чисел, будет также работать и с очередью символов механизм, который реализует связанный список почтовых адресов, будет также поддерживать связанный список запасных частей к автомобилям Т. е. можно создать класс, реализующий очередь, связанный список и т. д. для любых типов данных Компилятор будет автоматически генерировать правильный тип объекта на основе типа, заданного при создании объекта 3
Полиморфизм 4
Формализация template <class Фтип> class имя класса {. . . } Здесь Фтип — это формальное имя типа, который будет задан при создании экземпляра класса. При необходимости можно определить более одного типа данных, разделяя их запятыми. После создания класса-шаблона можно создать конкретный экземпляр этого класса: имя_класса <тип> объект; Здесь тип — это фактическое имя типа данных, с которым будет оперировать класс. 5
Пример: односв. список #include <iostream> using namespace std; template <class data_t> class list { data_t data; list *next; public: list (data_t d); void add(list *node) { node->next = this; next = 0; } list *getnext() { return next; } data_t getdata() { return data; } 6
Пример: односв. список template <class data_t> list<data_t>: : list(data_t d){ data = d; next = 0; } 7
Пример: односв. список int main(){ list<char> start('a'); list<char> *p, *last; int i; // создание списка last = &start; for(i = 1; i < 26; i++) { p = new list<char>(‘a’ + i); p->add(last); last = p; } // вывод списка p = &start; while(p) { cout << p->getdata(); p = p->getnext(); } return 0; 8
Пример: односв. список struct addr { char name[40]; char street[40]; char city[30]; char state[3]; char zip[12]; } list<addr> obj(structvar); 9
Перегрузка имени шаблона класса невозможна, поэтому никакая другая сущность не может быть объявлена в той же области видимости и с тем же именем, что и шаблон класса template<class T> class String{ /*. . . */}; //ошибка: двойное определение 10
Инстанцирование Процесс генерации объявления класса по шаблону класса и аргументу шаблона называется инстанцированием шаблона (template instantiation) Аналогично, функция генерируется ( «инстанцируется» ) из шаблона функции и аргумента шаблона Версия шаблона для конкретного аргумента шаблона называется специализацией Генерация версий функций шаблона для набора аргументов шаблона является задачей компилятора, а не программиста 11
Шаблон строк template<class C> class String { struct Srep; Srep *rep; public: String (); String (const C*); String (const String&); С read (int i) const; //. . . }; String<char> cs; void f() { String<Jchar> is; cs = "Какой код сгенерировать, решает компилятор"; } 12
Инстанцирование В этом случае компилятор генерирует объявления для String<char> и String<Jchar>, для их соответствующих типов Srep, для их деструкторов и конструкторов по умолчанию и для присваивания String<char>: : operator= (char*) Сгенерированные классы являются совершенно обычными классами, которые подчиняются всем стандартным правилам для классов Аналогично, сгенерированные функции являются обычными функциями, которые подчиняются всем стандартным правилам для функций Очевидно, что шаблоны обеспечивают эффективный способ генерации кода из сравнительно коротких определений. Поэтому требуется некоторая осмотрительность во избежание заполнения памяти почти идентичными определениями функций 13
Параметры шаблонов Параметрами шаблонов могут быть: параметры-типы, параметры обычных типов, такие как int, и параметрышаблоны Естественно, у шаблона может быть несколько параметров template<class T, Т def_val> class Cont {/*. . . */ }; 14
Шаблоны функций Для большинства людей наиболее очевидным применением шаблонов является определение и использование классов-контейнеров, таких как basicstring, vector и mар. Сразу же возникает потребность в шаблонах функций В качестве простого примера можно привести сортировку массива: template<class T> void sort (vector<T>&); // объявление void f(vector<int>& vi, vector<string>& vs) { sort(vi); // sort (vector<int>&); sort(vs); // sort (vector<string>&); } 15
Шаблоны функций template<class T> void sort (vector<T>& v) // определение //сортировка Шелла { const size tn = v. size(); for (int gap=n/2; 0<gap; gap /= 2) for (int i=gap; i<n; i++) for (int j=i-gap; 0<=j; j -= gap) if(v[j+gap] < v[j]) {// поменять v[j] и v[j+gap] T temp = v[j]; v[j] = v[j+gap]; v[j+gap] = temp; } 16
Соответствие сигнатуре и перегрузка template <class T> void swap(T& x, T& y) { T temp; temp = x; x = y; y = temp; } int i= 0, j=1; char ch 1='A', ch 2='B'; complex c 1 = 1. 0, c 2 = 2. 0; char* str 1 = "ABCD"; char* str 2 = "EFGHIJK"; swap(i, j); // ok swap(c 1, c 2); // ok swap(ch 1, ch 2); // ok swap(str 1, str 2); //wrong – меняем местами массивы 17
Соответствие сигнатуре и перегрузка void swap(char* s 1, char* s 2) { int max_len; max_len = (strlen(s 1) >= strlen(s 2)) ? strlen(s 1) : strlen(s 2); char* temp = new char[max_len + 1]; } strcpy(temp, s 1); strcpy(s 1, s 2); strcpy(s 2, temp); delete []temp; 18
Соответствие сигнатуре и перегрузка Выбор перегруженной функции n n n Строгое соответствие нешаблонной функции Строгое соответствие шаблонным функциям Обычное разрешение аргументов для нешаблонных функций 19
Lecture-OOP-11-Template.ppt