Слайд 1Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
ЯЗЫКИ ПРОГРАММИРОВАНИЯ
Шаблоны
Слайд 2Введение
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Шаблоны обеспечивают простой способ
введения разного рода общих концепций и простые методы их совместного использования.
Шаблоны обеспечивают непосредственную поддержку обобщенного программирования, то есть программирования с использованием типов в качестве параметров.
Слайд 3Введение
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Механизм шаблонов в С++
допускает использование типа в качестве параметра при определении класса или функции.
Шаблон зависит только от тех свойств параметра-типа, которые он явно использует, и не требует, чтобы различные типы, используемые в качестве аргументов, были связаны каким-либо другим образом.
Слайд 4Введение
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Стандартная библиотека должна обеспечивать
большую степень общности, гибкости и эффективности, чем большинство других программ.
Каждая существенная абстракция в стандартной библиотеке представлена в виде шаблона (например, string, ostream, complex, list и map), также как и все ключевые операции (например, сравнение строк, оператор вывода << , комплексное сложение, доступ к следующему элементу списка и сортировка).
Слайд 5Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Строка является
классом, который хранит символы и предоставляет операции, такие как доступ по индексу, конкатенацию и сравнение, которые мы обычно ассоциируем с понятием «строка».
Мы хотели бы реализовать такое поведение для многих наборов символов.
Слайд 6Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
class String
{
char* str;
int n;
public:
String(),
String(const char*);
String(const String&);
char read(int i) const;
};
Слайд 7Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
А что
если надо использовать wchar_t?
А если мы пишем класс для очереди. Для каждого типов данных исходных элементов писать свой класс?
Как написать общий класс, который позволил бы работать с «любыми» типами данных?
Слайд 8Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Любой шаблон начинается со
слова template, будь то шаблон функции или шаблон класса.
После ключевого слова template идут угловые скобки — < >, в которых перечисляется список параметров шаблона.
Каждому параметру должно предшествовать зарезервированное слово class или typename.
Слайд 9Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Некоторые примеры объявления шаблонов:
template
template
template
Слайд 10Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Ключевое слово typename говорит
о том, что в шаблоне будет использоваться встроенный тип данных, такой как: int, double, float, char и т. д.
Ключевое слово class сообщает компилятору, что в шаблоне функции в качестве параметра будут использоваться пользовательские типы данных, то есть классы.
Слайд 11Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
template
class String{
Ch* str;
int n;
public:
String(),
String(const Ch*);
String(const String&);
Сh read(int i) const;
// ....
};
Слайд 12Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Префикс template
Ch> указывает, что объявлен шаблон (template) и что аргумент Сh будет использован в объявлении как тип.
После объявления Сh используется точно также, как имена других типов.
Область видимости Сh простирается до конца объявления, начинающегося с template. Обратите внимание, что template означает, что Сh — это имя пользовательского типа, а не обязательно имя класса
Слайд 13Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Имя шаблона
класса, за которым следует тип, помещенный в угловые скобки < >, является именем класса (определяемого шаблоном) и его можно использовать точно также, как имена других классов.
Примеры
String cs;
String us;
String ws;
class Jchar {
// японские символы
};
String js;
Слайд 14Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
За исключением
специального синтаксиса своего имени String работает точно также, как если бы он был определен как String.
То, что мы сделали String шаблоном, позволит нам реализовать средства, которые мы ввели для строк char, для строк с любыми символами.
Слайд 15Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
#include
#include
Слайд 16Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
#include
#include
Слайд 17Простой шаблон строк
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Стандартная библиотека
предоставляет шаблон класса basic string. В стандартной библиотеке string определен как синоним basic_string:
typedef basic_string string;
Слайд 18Определение шаблона
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Класс, генерируемый из
шаблона класса, является совершенно нормальным классом.
Поэтому использование шаблона не подразумевает каких-либо дополнительных механизмов времени выполнения сверх тех, что использовались бы для эквивалентного написанного «вручную» класса.
Слайд 19Определение шаблона
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Как правило, неплохой
идеей является протестировать конкретный класс, например String, до преобразования его в шаблон (String).
Поступая таким образом, мы решаем многие проблемы проектирования и обнаруживаем большую часть ошибок кода в контексте конкретного примера.
Слайд 20Определение шаблона
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Члены шаблона класса
объявляются и определяются точно также, как и для обычного класса.
Член шаблона не обязательно определять внутри самого шаблона.
Члены шаблона класса в свою очередь являются шаблонами, параметризованными при помощи аргументов шаблона.
Слайд 21Определение шаблона
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
template class
String{
struct Srep;
Srep *rep;
public:
String(),
String(const Ch*);
String(const String&);
Сh read(int i) const;
// ....
};
template String<Сh>::String()
{
str = new Сh();
n = 0;
}
Слайд 22Определение шаблона
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
template class
String{
Ch* str;
int n;
public:
String();
friend istream& operator>> (istream& io, String& str);
friend ostream& operator<< (ostream& io, String& str);
// ....
};
template istream& operator>>(istream& io, String& _str)
{
io >> _str.str;
return io;
}
template ostream& operator<<(ostream& io, String& _str)
{
io << _str.str;
return io;
}
Слайд 23Инстанцирование
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Процесс генерации объявления класса
по шаблону класса и аргументу шаблона часто называется инсшанцированием шаблона (template instantiation)
Аналогично, функция генерируется («инстанцируется») из шаблона функции и аргумента шаблона.
Версия шаблона для конкретного аргумента шаблона называется специализацией.
Слайд 24Инстанцирование
Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Генерация версий функций шаблона
для набора аргументов шаблона является задачей компилятора, а не программиста.
String cs;
void f()
{
String js;
cs = "Какой код сгенерировать, решает компилятор";
}
Слайд 25Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
В этом случае компилятор
генерирует объявления для String и String, для их соответствующих типов, для их деструкторов и конструкторов по умолчанию и для присваивания String::operator= (char*) и т.д.
Слайд 26Никитин Михаил Евгеньевич, 2015
Политехнический колледж имени П.А. Овчинникова
Сгенерированные классы являются совершенно
обычными классами, которые подчиняются всем стандартным правилам для классов.
Аналогично, сгенерированные функции являются обычными функциями, которые подчиняются всем стандартным правилам для функций.