Шаблоны с языке С++. Лекция 11 (1)

Содержание

Слайд 2

Универсальным алгоритмом будем называть алгоритм, не привязанный к определенному типу входных и

Универсальным алгоритмом будем называть алгоритм, не привязанный к определенному типу входных и
выходных данных, т.е. одинаково хорошо работающий с данными разного типа.
Например, любой из алгоритмов сортировки (выбором, обменом и т.д.) может применяться к массивам разного типа (int, float, double, и др.).
Универсальный алгоритм может быть реализован в виде функции С++, однако для каждого типа входных данных необходимо будет определить свою собственную функцию, то есть перегрузить функцию несколько раз.

Универсальный алгоритм

Слайд 3

void bubble_sort(int data[], int n)
{
...
}
void bubble_sort(float data[], int

void bubble_sort(int data[], int n) { ... } void bubble_sort(float data[], int
n)
{
...
}
void bubble_sort(my_class data[], int n)
{
...
}

Такой способ реализации допустим в С++, но его нельзя считать удобным.

Слайд 4

Решение 1: псевдоним типа (typedef)

typedef T int;
T summa(T array[], int

Решение 1: псевдоним типа (typedef) typedef T int; T summa(T array[], int
size)
{
T res = 0;
for(int i=0; i res += array[i];
return res;
}

Такая функция может работать с любыми числовыми данными, но
требует переопределения псевдонима T,
не может применяться одновременно к двум типам.

Слайд 5

Универсальный алгоритм в С++ может быть реализован с помощью шаблона функции.
Определение

Универсальный алгоритм в С++ может быть реализован с помощью шаблона функции. Определение
шаблона похоже на определение обычной функции, но при этом используют ключевое слово template, вслед за которым указывают аргументы в угловых скобках.
Формальные параметры шаблона
перечисляются через запятую
могут быть именами типов, именами других шаблонов и именами объектов.
Параметр-тип описывается с помощью ключевых слов class или typename.

Решение 2: шаблон функции С++

Слайд 6

Синтаксис определения

Определение шаблона функции


template <параметры_шаблона>
тип имя_функции(список_аргументов)
{
операторы;

Синтаксис определения Определение шаблона функции template тип имя_функции(список_аргументов) { операторы; }; В
};

В теле шаблона функции могут использоваться и формальные аргументы функции, и формальные параметры шаблона.

Слайд 7

template
T summa(T array[], int size)
{
T res

template T summa(T array[], int size) { T res = 0; for
= 0;
for (int i=0; i res += array[i];
return res;
}

Пример: шаблон функции для расчета суммы элементов массива

Слайд 8

При вызове функции-шаблона, после ее имени указывают фактические параметры шаблона в угловых

При вызове функции-шаблона, после ее имени указывают фактические параметры шаблона в угловых
скобках, а затем фактические аргументы функции в круглых скобках.

Вызов функции-шаблона


имя <факт_параметры>(факт_аргументы);
int iarray[10];
int i_sum;
//...
i_sum = summa(iarray, 10);

Пример:

Слайд 9

Шаблоны можно параметризовать не только именами типов, но и объектами, поэтому аргумент

Шаблоны можно параметризовать не только именами типов, но и объектами, поэтому аргумент
size можно указать в списке параметров шаблона

Объект – параметр шаблона


template
T summa (T array[])
{
...
}
i_sum = summa (iarray);

объявление

вызов

Слайд 10

Параметрами шаблона могут быть
− параметр-тип (имя типа – int, float, string

Параметрами шаблона могут быть − параметр-тип (имя типа – int, float, string
и т.д.)
− параметр-шаблон (имя другого шаблона)
− параметр-объект или параметр-переменная

Параметром-переменной могут быть переменные следующих типов
интегральный (целые, символьные и логические)
перечислимый,
указатель на объект любого типа или на функцию
ссылка на объект любого типа или на функцию
указатель на член класса

Слайд 11

Параметром-переменной в шаблоне не может быть:
− void
− пользовательский тип

Параметром-переменной в шаблоне не может быть: − void − пользовательский тип −
вещественный тип (float, double)

template class X{ ... }; // ОК
template class X{ ... }; // ошибка*
template class X{ ... }; // OK
template class X{ ... }; // OK

Примеры

Слайд 12

Шаблон в языке С++ реализует принципы параметрического полиморфизма, то есть возможности применять

Шаблон в языке С++ реализует принципы параметрического полиморфизма, то есть возможности применять
один и тот же алгоритм для разных типов данных.
Шаблоны широко используются при разработке библиотек. Стандартная библиотека шаблонов (Standard Template Library, STL) – пример такой библиотеки.
Универсальные алгоритмы STL – find, replace, shuffle, accumulate, merge, и др.

Шаблоны и параметрический полиморфизм

Слайд 13

Если к какому-либо конкретному типу аргументов шаблонный алгоритм неприменим, то можно определить

Если к какому-либо конкретному типу аргументов шаблонный алгоритм неприменим, то можно определить
обычную функцию, список типов аргументов и возвращаемого значения которой соответствуют объявлению шаблона.
Функция, перегружающая шаблон, называется специализацией шаблонной функции.

Специализация шаблона

Пример: алгоритм суммирования в применении к массиву символов (текстовой строке)

Слайд 14

Иногда при вызове шаблона функции после имени можно не указывать фактические параметры

Иногда при вызове шаблона функции после имени можно не указывать фактические параметры
в угловых скобках. В этом случае компилятор сам определит параметры шаблона по типу параметров функции.
Эта особенность называется выведением типов аргументов шаблона.

Выведение типов
int iarray[10];
int i_sum;
//...
i_sum = summa(iarray, 10);

Слайд 15

При выведении типов могут применяться только преобразования точного отождествления, то есть:

Преобразование

При выведении типов могут применяться только преобразования точного отождествления, то есть: Преобразование
типов

T[] <-> T*
T <-> T&
T -> const T

точное совпадение
совпадение с точностью до typedef
тривиальные преобразования:

Слайд 16

Пример преобразования типов
template
T max(T t1, T t2){...}
int main()
{

Пример преобразования типов template T max(T t1, T t2){...} int main() {
max(1,2); // max(1,2);
max(’a’,’b’); // max(’a’,’b’);
max(2.7, 4.9); // max(2.7, 4.9);
//max(’a’,1); // ошибка – неоднозначность,
// станд. преобразования не
// допускаются
//max(2.5,4); // ошибка – неоднозначность,
// станд. преобразования не
// допускаются
}

Слайд 17

Устранение неоднозначности
max (’a’,1);
max (2.5,4);

Неоднозначности не возникают при

Устранение неоднозначности max (’a’,1); max (2.5,4); Неоднозначности не возникают при использовании явного квалификатора типа шаблона
использовании явного квалификатора типа шаблона

Слайд 18

Универсальным контейнером будем называть программную структуру, которая может использоваться для хранения данных

Универсальным контейнером будем называть программную структуру, которая может использоваться для хранения данных
разных типов.
Такие контейнеры также могут быть реализованы с помощью шаблонов С++. Однако в этом случае создается не шаблон функций, а шаблон целого класса.
Пример: контейнер vector для хранения коллекции однотипных данных (аналог массива). В контейнере vector могут храниться данные любого типа (int, float, double, char, и др.). Содержится в библиотеке STL.

Универсальные контейнеры

Слайд 19

Синтаксис объявления

Объявление шаблона класса


template <параметры_шаблона>
class имя_класса
{
поля и

Синтаксис объявления Объявление шаблона класса template class имя_класса { поля и методы;
методы;
};

В объявлении класса-шаблона используются формальные параметры шаблона.

Слайд 20

Создание объекта шаблонного класса называется инстанцированием шаблона.
Синтаксис инстанцирования

Создание объекта


имя_класса <параметры_шаблона>

Создание объекта шаблонного класса называется инстанцированием шаблона. Синтаксис инстанцирования Создание объекта имя_класса объект;
объект;

Слайд 21

Пример: пара чисел
template
class pair
{
private:

Пример: пара чисел template class pair { private: T1 data1; T2 data2;
T1 data1;
T2 data2;
public:
pair(T1 d1, T2 d2): data1(d1),data2(d2){};
void print()
{
cout << data1 << ”,” << data2 << endl;
}
}

Слайд 22

pair c1(5, ’S’);
pair c2(0.39, false);

pair c1(5, ’S’); pair c2(0.39, false); c1.print(); c2.print(); Примеры инстанцирования шаблона класса
c1.print();
c2.print();

Примеры инстанцирования шаблона класса pair

Для корректного функционирования шаблона с конкретными типами T1 и T2 необходимо, чтобы для этих типов были определены процедуры инициализации (data1(d2)) и вывода объекта в поток (ostream << data1).

Слайд 23

Пример 2: шаблон массива

Задача: создать шаблон класса array, позволяющего хранить данные любого

Пример 2: шаблон массива Задача: создать шаблон класса array, позволяющего хранить данные
типа. Предусмотреть следующие возможности:
1) доступ к элементам по индексу
2) средства контроля выхода за пределы
3) массив произвольной длины
В качестве параметров шаблона будем использовать тип элементов T и количество элементов n.

Слайд 24

#include
#include
template
class array
{
public:

#include #include template class array { public: array(); ~array(); T& operator[](int k); private: T *data; };
array();
~array();
T& operator[](int k);
private:
T *data;
};

Слайд 25

template
array::array()
{
data = new T[n];
}
template

template array ::array() { data = new T[n]; } template array ::~array() { delete []data; }

array::~array()
{
delete []data;
}

Слайд 26

template
T& array::operator[](int k)
{
if( k<0 ||

template T& array ::operator[](int k) { if( k =n ) throw std::out_of_range("Out!");
k>=n )
throw std::out_of_range("Out!");
return data[k];
}
template
std::ostream& operator <<
(std::ostream& os, array& obj)
{
os << "\nСодержимое массива:";
for(int i=0; i os << endl << obj[i];
return os;
}
Имя файла: Шаблоны-с-языке-С++.-Лекция-11-(1).pptx
Количество просмотров: 57
Количество скачиваний: 2