Лекция 21. Шаблоны (часть 1) презентация

Содержание


Презентации» Шаблоны, фоны презентаций» Лекция 21. Шаблоны (часть 1)
Лекция 21. Шаблоны (часть 1)
 Красс Александр
 Alexander.Krass@gmail.comШаблоны
 Введение в шаблоны
 Шаблоны функций
 Инстанцирование шаблонов функций
 Явное инстанцированиеВведение в шаблоны (Простой пример)
 Напишем функцию, возвращающую максимум из двухВведение в шаблоны
 Вместо этого воспользуемся механизмом шаблонов:
 template < typenameВведение в шаблоны (как это работает)
 Имеем функцию
 template < typenameВсе эти действия выполняются автоматически.
 Все эти действия выполняются автоматически.
 КомпиляторИнстанцирование шаблонов (требования к типам)
 Снова рассмотрим нашу функцию Max:
 templateИнстанцирование шаблонов (требования к типам)
 Компилятор сгенерирует функцию Max для типаИнстанцирование шаблонов (требования к типам)
 Выводы:
 Инстанцирование шаблона для некоторого типаЯвное инстанцирование шаблонов
 Рассмотрим функцию spaceOf, возвращающую размер типа в 32-битныхЯвное инстанцирование шаблонов
 Решение заключается в использовании явного инстанцирования шаблона:
 intШаблоны или макросы
 Нашу функцию Max можно реализовать и через макрос:
Шаблоны или макросы (Сравнение)Шаблоны классов
 Рассмотрим класс, реализующий стек целых чисел:
 class Stack
 {
Шаблоны классов
 Решение заключается в использовании шаблонного класса Stack:
 template <Шаблоны классов
 Класс – это тип.
 Шаблонный класс это не тип.Шаблоны классов
 Поскольку шаблонный класс это не тип, а множество типов,Инстанцирование шаблонов (требования к типам)
 Рассмотрим реализацию функции push из нашегоУлучшение класса Stack
 Рассмотрим еще раз наш класс Stack
 template <Улучшение класса Stack
 Можно. Наш класс Stack хранит ровно 100 элементов.
Аргументы шаблонов
 Аргументом шаблона (как функции, так и класса) могут быть:
Определение членов класса
 Функции-члены класса можно реализовывать двумя способами:Аргументы по умолчанию
 Можно так:
 template <typename elem = char>
 class



Слайды и текст этой презентации
Слайд 1
Описание слайда:
Лекция 21. Шаблоны (часть 1) Красс Александр Alexander.Krass@gmail.com


Слайд 2
Описание слайда:
Шаблоны Введение в шаблоны Шаблоны функций Инстанцирование шаблонов функций Явное инстанцирование шаблонов Шаблоны vs Макросы Шаблоны классов

Слайд 3
Описание слайда:
Введение в шаблоны (Простой пример) Напишем функцию, возвращающую максимум из двух целых чисел: int Max (int a, int b) { return (a > b) ? a : b; } А что делать, если нам нужна эта функция для различных случаев: Разные типы (int, float) Решается перегрузкой Типы, о которых мы ничего не знаем в момент написания функции Max Также решается перегрузкой, но свою версию этой функции должен реализовывать тот, кто придумал и реализовал этот тип. Перегрузка не выход: Все версии функций надо тестировать Мы не всегда знаем, какие типы будут использоваться для нашей функции

Слайд 4
Описание слайда:
Введение в шаблоны Вместо этого воспользуемся механизмом шаблонов: template < typename T > T Max ( T a, T b ) { return a>b ? a : b; } template – ключевое слово, говорящее о том, что мы объявляем шаблон. typename – ключевое слово, говорящее о том, что T это не неизвестный тип. Пример использования функции Max: res = Max(1, 2); // Синтаксис вызова такой // же, как и для обычной // функции.

Слайд 5
Описание слайда:
Введение в шаблоны (как это работает) Имеем функцию template < typename T > T Max (T a, T b) { return (a > b) ? a : b; } Вызываем ее int res = Max(1, 0); 3. Компилятор генерирует реализацию функции Max (инстанциирует шаблон) для типов int и вставляет ее вызов: int Max_Int(int a, int b) { return a > b ? a : b; }

Слайд 6
Описание слайда:
Все эти действия выполняются автоматически. Все эти действия выполняются автоматически. Компилятор производит замену формальных типов на фактические посредством анализа аргументы функции в месте вызова. Инстанцирование шаблона происходит один раз для каждого набора типов аргументов в рамках одной единицы трансляции. Имеем шаблонную функцию Max. Вызываем ее из файла main.cpp Компилятор инстанцирует шаблон Вызываем ее еще раз из файла second.cpp Компилятор второй раз инстанцирует шаблон Тип возвращаемого значения не учитывается при инстанциировании шаблона.

Слайд 7
Описание слайда:
Инстанцирование шаблонов (требования к типам) Снова рассмотрим нашу функцию Max: template < typename T > T Max (T a, T b) { return (a > b) ? a : b; } Определим новый тип: class C { public: C() : m(0) {} int m; }; И вызовем Max для переменных типа C: C c1, c2; Max(c1, c2); // Будет ли это компилироваться?

Слайд 8
Описание слайда:
Инстанцирование шаблонов (требования к типам) Компилятор сгенерирует функцию Max для типа C: C Max_C(C a, C b) { return a > b ? a : b; } Эта функция компилироваться не будет, т.к. класс C не содержит оператора >

Слайд 9
Описание слайда:
Инстанцирование шаблонов (требования к типам) Выводы: Инстанцирование шаблона для некоторого типа будет выполнено если и только если этот тип поддерживает все операторы, используемые в шаблоне Возможно, в комментариях к шаблону имеет смысл указывать, какие операции должны поддерживать аргументы шаблона: // This function template implements the common case of calculating maximum // Actual type for the template instantiation should have ‘>’ operator defined. template < typename T> T Max ( T, T ); При разработке своих типов имеет смысл реализовывать все основные операции. К сожалению, C++ не позволяет указывать требования к аргументам шаблона на этапе компиляции: template < typename T with bool operator>(T,T) > // Это не скомпилируется! T Max ( T, T );

Слайд 10
Описание слайда:
Явное инстанцирование шаблонов Рассмотрим функцию spaceOf, возвращающую размер типа в 32-битных словах: template <typename T> int spaceOf() { int bytes = sizeof(T); return (bytes + 3) >> 2; } Как ее вызвать? int i = spaceOf(); // так работать не будет Как компилятор определит тип, с которым вызывается шаблон.

Слайд 11
Описание слайда:
Явное инстанцирование шаблонов Решение заключается в использовании явного инстанцирования шаблона: int wint = spaceOf<int>(); int warr = spaceOf<int[10]>();

Слайд 12
Описание слайда:
Шаблоны или макросы Нашу функцию Max можно реализовать и через макрос: // Template representation template < typename T > T Max ( T a, T b ) { return a>b ? a : b; } // ”Traditional” representation #define Max(a,b) ((a)>(b)?(a):(b)) Так почему же шаблоны лучше чем макросы?

Слайд 13
Описание слайда:
Шаблоны или макросы (Сравнение)

Слайд 14
Описание слайда:
Шаблоны классов Рассмотрим класс, реализующий стек целых чисел: class Stack { public: Stack() : top(-1) { } void push (int value) { S[++top] = value; } int pop() { return S[top--]; } // other operations . . . private: int top; int S[100]; }; Использование: Stack s; s.push(0); Хорошо бы этот класс использовать и для других типов.

Слайд 15
Описание слайда:
Шаблоны классов Решение заключается в использовании шаблонного класса Stack: template < typename T > class Stack { public: Stack() : top(-1) { } void push(T value) { S[++top] = value ; } T pop() { return S[top--]; } . . . private: int top; T S[100]; }; Использование: Stack<int> s; s.push(0);

Слайд 16
Описание слайда:
Шаблоны классов Класс – это тип. Шаблонный класс это не тип. Это множество типов. Шаблонная функция это не функция. Это множество функций (перегруженных).

Слайд 17
Описание слайда:
Шаблоны классов Поскольку шаблонный класс это не тип, а множество типов, мы должны инстанциировать шаблон перед использованием. Инстанциирование шаблонного класса подразумевает генерацию нового класса с заменой формальных параметров шаблона на реальные. Шаблонный класс ВСЕГДА инстанциируется явно.

Слайд 18
Описание слайда:
Инстанцирование шаблонов (требования к типам) Рассмотрим реализацию функции push из нашего класса Stack: void push(T v) { S[++top] = v;} Здесь используется конструктор копирования и оператор присваивания. Т.е., если мы хотим использовать класс Stack для нашего типа, мы должны предоставить конструктор копирования и оператор присваивания для этого типа. Использование конструктора копирования может привести к тормозам. Решение: void push (const T &v) { S[++top] = v; }

Слайд 19
Описание слайда:
Улучшение класса Stack Рассмотрим еще раз наш класс Stack template < typename T > class Stack { public: Stack() : top(-1) { } void push(T v) { S[++top] = v; } T pop() {return S[top--]; } // other operations . . . private: int top; T S[100]; }; Можно ли его сделать более общим?

Слайд 20
Описание слайда:
Улучшение класса Stack Можно. Наш класс Stack хранит ровно 100 элементов. template < typename T, int N > class Stack { public: Stack() : top(-1) { } void push ( T& V ) { S[++top] = V; } T pop (void) { return S[--top]; } . . . private: int top; T S[N]; } Использование: Stack<int, 200> s;

Слайд 21
Описание слайда:
Аргументы шаблонов Аргументом шаблона (как функции, так и класса) могут быть: Типы Интегральное константное выражение Указатель на объект или на функцию Ссылка на объект или функцию Указатель на член класса Другими словами, аргумент шаблона должен вычисляться во время компиляции.

Слайд 22
Описание слайда:
Определение членов класса Функции-члены класса можно реализовывать двумя способами:

Слайд 23
Описание слайда:
Аргументы по умолчанию Можно так: template <typename elem = char> class String { … elem str[100]; }; Или вот так: template <int N = 10, typename elem = char> class String { … elem *tr[N]; }; А вот так нельзя: template <int N = 10, typename elem> class String {};


Скачать презентацию на тему Лекция 21. Шаблоны (часть 1) можно ниже:

Похожие презентации