Лекция-2.05.ppt
- Количество слайдов: 18
Шаблоны 1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 1
Понятие шаблона основывается на предположении, что поведение объектов одинаково для различных типов данных и поэтому достаточно разработать только один обобщенный класс. Однако иногда это предположение не выполняется, и для некоторых типов некоторые детали поведения объектов должны быть реализованы по-разному. Язык C++ поддерживает концепцию специализации при работе с параметрами типа, которые требуют специальной обработки. Для каждого специального класса должен предусматриваться отдельный специализированный шаблон класса. Синтаксис описания специализации представляет собой объединение синтаксиса для самого шаблонного класса и инициализации шаблона в клиентской программе. Параметр типа берется из списка параметров шаблона и перемещается в список фактических типов. Лекция 20. 03. 2014 г. 2
Пример явной специализации шаблона класса. Пусть имеется шаблон класса, реализующий обобщенный массив произвольной длины из элементов произвольного типа: template <class T, int N> class ARRAY { T arr[N]; . . . }; Для общего случая реализация такого массива будет достаточно сложной, однако для частного случая массива булевских элементов размером не более ширины аппаратно поддерживаемого машинного слова можно предложить значительно более эффективную реализацию, использующую логические операции и операции сдвигов. Такая реализация оформляется в виде явной специализации "общего" шаблона для конкретных значений параметров. template <> class ARRAY<bool, 32> { unsigned long Scale; . . . }; Лекция 20. 03. 2014 г. 3
Частичные специализации шаблона класса. Механизм частичных специализаций заключается в возможности задания для некоторых подмножеств параметров шаблона специфической реализации, отличной от реализации для "общего случая". Так, для некоторого шаблона : template<class T, int N> class C {. . . }; можно определить версию не для всех возможных типов, а только для указателей: template<class T, int N> class C<T*, N> {. . . }; Допускается фиксация одного параметра (то есть, задание для него конкретного значения): template<class T> class C<T, 2> {. . . }; Для одного описания шаблона допускается неограниченное множество его частичных специализаций. Лекция 20. 03. 2014 г. 4
1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 5
Функции-члены шаблонов классов. Как и для обычных классов, функция-член шаблона класса может быть определена внутри определения шаблона (и тогда она называется встроенной – inline), либо вне его. Функция-член шаблона класса сама является шаблоном. При инстанцировании функции-члена используется тип того объекта, для которого она вызвана. template <class Type> class Stack {. . . public: void push(const Type&){. . . } // определение внутри шаблона. . . }; . . . template <class T> void Stack<T>: : push (const T& c){. . . } // определение вне шаблона. . . Pt *z[]; Stack<Pt> s(4); . . . s. push(*z[i]); Лекция 20. 03. 2014 г. 6
1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 7
Аналогично шаблонам классов, шаблон функции в С++ является способом задания семейства одноименных совместно используемых (перегружаемых – overloaded) функций, возможно, различающихся количеством и типами параметров и атрибутами внутреннего устройства. Синтаксис определения внешней функции-шаблона подобен синтаксису функций-членов шаблонных классов: template <class Т> void swap(T& х, Т& у) { Т а = х; x = у; у = а; } Лекция 20. 03. 2014 г. 8
Обрабатывая определение шаблонной функции, компилятор не генерирует объектный код. Создание экземпляра шаблонной функции осуществляется при ее вызове. Настройка шаблона выполняется по типам фактических параметров. int а=5, b=10; double с=3. 0, d=4. 0; swap(a, b); // создание экземпляра функции для int swap(c, d); // создание экземпляра функции для double Для параметров шаблона неявные преобразования не применяются. Если компилятор не может решить, какую функцию сгенерировать для точного соответствия параметров, это приводит к синтаксической ошибке. swap(a, c); // синтаксическая ошибка: нет точного соответствия Лекция 20. 03. 2014 г. 9
1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 10
Допускается перегрузка шаблонных функций. Предусматривается, что они могут различаться по типам фактических параметров или по количеству параметров. template <class Т> inline void swap(T& x, T& у, Т& z) { Т а = х; x = у; у = z; z = а; } int а=5, b=10, с=20; swap(a, b); swap(a, b, c); Лекция 20. 03. 2014 г. 11
1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 12
Шаблонные функции могут специализироваться для конкретных типов. Например, символьные массивы не могут переставляться как целые, должна использоваться специализированная версия. Правила формирования специализаций шаблонов функций те же, что и для специализаций шаблонных классов. Пример специализированной функции swap() приведен на следующем слайде. Лекция 20. 03. 2014 г. 13
template < > inline void swap <char*> (char* x, char* y) { char* a = new char[strlen(x)+1] ; char* b = new char[strlen(y)+1] ; strcpy(a, x); strcpy(b, y); // память должна обеспечить вызывающая программа strcpy(x, b); strcpy(y, a); delete a; delete b; } Клиентская программа: char x[20]="abc", y[20]="defgh"; int a=5, b=10; swap(a, b); // создается экземпляр общей шаблонной функции swap(x, y); // создается экземпляр специализированной // шаблонной функции Лекция 20. 03. 2014 г. 14
1. Концепция параметризуемых типов. 2. Шаблоны классов. 3. Шаблоны классов с несколькими параметрами. 4. Специализации шаблонов классов. Явные и частичные специализации. 5. Функции-члены шаблонов классов. 6. Шаблоны функций. 7. Перегрузка шаблонных функций. 8. Специализации шаблонных функций. 9. Объявления друзей в шаблонах классов. Лекция 20. 03. 2014 г. 15
В шаблон класса можно поместить три вида объявления друзей: 1. Обычные (не шаблонные) функция - друг или класс - друг: void f 1() {. . . } class A {. . . }; class B {void f. B() {. . . }; template <class T> class C { friend void f 1(); // внешняя функция - друг friend void B: : f. B(); // функция класса - друг friend class A; // класс - друг. . . }; Лекция 20. 03. 2014 г. 16
Второй вид друзей в шаблоне класса: 2. Связанные между собой шаблон функции - друг или шаблон класс - друг: template <class T> void f 1(T x) {. . . } template <class T> class A {. . . }; template <class T> class B { void f. B() {. . . }; template <class T> class C { friend void f 1<T>(T x); // внешний шаблон функции - друг friend void B<T>: : f. B(); // функция шаблона класса - друг friend class A<T>; // шаблон класса - друг. . . }; Лекция 20. 03. 2014 г. 17
Третий вид друзей в шаблоне класса: 3. Несвязанные шаблон функции - друг или шаблон класс - друг: template <class T> void f 1(T x) {. . . } template <class T> class A {. . . }; template <class T> class B { void f. B() {. . . }; template <class T 1> class C { template <class T> friend void f 1(T x); // внешний шаблон функции - друг template <class T> friend void B<T>: : f. B(); // функция шаблона класса - друг template <class T> friend class A; // шаблон класса - друг. . . }; Лекция 20. 03. 2014 г. 18
Лекция-2.05.ppt