SlideShare a Scribd company logo
Шаблоны
ЛЕКЦИЯ	
  №7
Два	
  вида	
  многократного	
  
использования	
  кода
Наследование
• Создаем	
  структуру	
  для	
  работы	
  с	
  
«базовым	
  классом»
• Создаем	
  классы-­‐наследники	
  на	
  каждый	
  
случай.
Шаблоны
• Описываем	
  «стратегию	
  работы»	
  с	
  
«неопределенным»	
  классом.
• Компилятор	
  в	
  момент	
  создание	
  класса	
  по	
  
шаблону,	
  сам	
  создает	
  нужный	
  «код»	
  для	
  
конкретного	
  класса.
Template	
  это	
  …
• Шаблон	
  – это	
  параметрическая	
  функция	
  или	
  класс.
• Параметром	
  может	
  являться	
  как	
  значение	
  переменной	
  (как	
  в	
  
обычных	
  функциях)	
  так	
  и	
  тип	
  данных.
• Параметры	
  подставляются	
  на	
  этапе	
  компиляции	
  программы.
• Подставляя	
  параметры	
  в	
  шаблон	
  – мы	
  конструируем	
  новый	
  тип	
  
данных	
  (или	
  функцию,	
  если	
  это	
  шаблон	
  функции)	
  
Простой	
  шаблон
Example50_Template
template <class T> class Print
{
public:
Print(T value)
{
std::cout << "Value:" << value <<
std::endl;
};
};
Перед	
  описанием	
  класса	
  ставим	
  ключевое	
  
слово	
  template	
  <class	
  T>
T	
  – используем	
  вместо	
  имени	
  класса,	
  
который	
  будет	
  заменяться	
  при	
  создании	
  
конкретного	
  экземпляра	
  класса.
Print – это	
  шаблон
Print<int> -­‐ это	
  класс,	
  
сконструированный	
  по	
  шаблону
Несколько	
  параметров	
  и	
  шаблоны-­‐функции
Example51_MultiTemplate
Параметры	
  указываются	
  через	
  запятую:
template <class A, class B> class Sum { …}
Оператор,	
  принимающий	
  в	
  качестве	
  параметра	
  – шаблон	
  с	
  
параметрами:
template <class A, class B> std::ostream& operator<<(std::ostream & os, Sum<A, B> &sum)
Параметры	
  – переменные
Example52_ComplexParameters
1.template <class TYPE, TYPE def_value, size_t SIZE = 10 > class Array {
2.protected:
3. TYPE _array[SIZE];
4.public:
5. Array() {
6. for (int i = 0; i < SIZE; i++) {
7. _array[i] = def_value;
8. }
9. }
10. const size_t size() {
11. return SIZE;
12. }
13. const TYPE operator[](size_t index) {
14. if ((index >= 0) && (index < SIZE)) return _array[index];
15. else throw BadIndexException(index, SIZE);
16. }
17.};
Специализация	
  шаблонов
Example53_TemplateSpecialization
template <class T>
class mycontainer {
// …
};
template <>
class mycontainer <char> {
// ..
};
Иногда	
  бывает	
  необходимость	
  сделать	
  
специальную	
  реализацию	
  шаблона	
  для	
  
какого-­‐либо	
  типа.
В	
  этом	
  случае,	
  можно	
  описать	
  отдельную	
  
реализацию	
  класса,	
  дополнив	
  его	
  новыми	
  
методами	
  или	
  переопределив	
  реализацию	
  
существующих.
Можно	
  специализировать	
  только	
  часть	
  
параметров
Example54_TemplateSpecialization2
template <class A, class B,
class C> class Sum {
…
}
template <class A, class B>
class Sum<A, B, const char*> {
…
}
При	
  частичной	
  специализации	
  у	
  шаблона	
  
становится	
  меньше	
  параметров	
  (какие-­‐то	
  
мы	
  уже	
  указали	
  явно).
Частичная	
  специализация	
  работает	
  только	
  с	
  
классами	
  (с	
  функциями	
  не	
  работает).
Вычисляем	
  факториал
Example54_Factorial
1.// факториал с помощью функций
2.template <uint64_t value> uint64_t Factorial(){
3. return Factorial<value-1>()*value;
4.}
5.template <> uint64_t Factorial<0>(){
6. return 1;
7.}
8.// факториал с помощью классов
9.template<uint64_t n>class fact{
10. public:
11. static const uint64_t value = fact<n-1>::value * n;
12.};
13. template<>class fact<0>{
14. public:
15. static const uint64_t value = 1;
16.};
Templates
две	
  модели
1.	
  Наиболее	
  популярный	
  подход	
  -­‐ модель	
  
включения(inclusion model),	
  определения	
  
шаблонов	
  полностью	
  размещаются	
  в	
  
заголовочном	
  файле.
2.	
  Модель	
  явного	
  инстанцирования (explicit
instantiation model),	
  как	
  правило	
  реализуется	
  
директивой	
  явного	
  инстанцирования (explicit
instantiation directive).
Inclusion	
  model
template<class T> class stack {
T* v;
T* p;
int sz;
public:
stack(int s) { v = p = new T[sz=s]; }
~stack() { delete[] v; }
void push(T a) { *p++ = a; }
T pop() { return *--p; }
int size() const { return p-v; }
};
И	
  объявление	
  и	
  описание	
  шаблона	
  
располагается	
  в	
  header	
  файле	
  (.h)
Фактически,	
  при	
  любом	
  
подключении	
  к	
  .cpp файлу	
  – это	
  
будет	
  новый	
  шаблон	
  для	
  
компилятора.
Минус	
  такой	
  модели	
  в	
  том,	
  что	
  
трудно	
  читать	
  код	
  (все	
  перемешано).
explicit instantiation model
Example55_ExplicitInstantiation
template <class T> class
MyStack
{
public:
MyStack(void);
};
template <class T>
MyStack<T>::MyStack(void)
{
_size = 0;
_current = NULL;
}
template class MyStack<class
MyClass>;
В	
  продолжение	
  примера
1. В	
  качестве	
  параметра	
  шаблона	
  можно	
  передавать	
  указатели	
  на	
  функции	
  (если	
  работать	
  
не	
  с	
  указателями	
  – то	
  это	
  уже	
  будет	
  вызов	
  функции	
  J )
2. В	
  примере	
  «параметр-­‐функция»	
  нам	
  понадобился	
  что	
  бы	
  удалять	
  указатели.	
  Если	
  бы	
  
мы	
  в	
  коде	
  написали	
  «delete	
  old-­‐>item»	
  то	
  такой	
  код	
  не	
  скомпилировался	
  бы	
  для	
  класса	
  
MyStack<MyClass>.
3. А	
  вот	
  для	
  MyStack<MyClass*>	
  -­‐ скомпилировался	
  бы.
Шаблоны	
  с	
  переменным	
  числом	
  
параметров
Example56_VariadicTemplate
template <class T> void print(const T&
t) {
std::cout << t << std::endl;
}
template <class First, class... Rest>
void print(const First& first, const
Rest&... rest) {
print(rest...);
}
• В	
  C++	
  есть	
  возможность	
  сделать	
  шаблон	
  с	
  
переменным	
  числом	
  параметров.
• В	
  этом	
  случае	
  используется	
  «…»	
  для	
  
указания	
  списка	
  параметров.
• Работать	
  с	
  такими	
  шаблонами	
  можно	
  по	
  
принципу	
  рекурсии.
Variadic template	
  в	
  структурах	
  данных
Example57_VariadicTemplate2
1.// Конец рекурсии
2.template <class... Ts> class tuple {};
3.// Шаблон
4.template <class T, class... Ts>
5.// Класс наследник самого себя но с меньшим числом параметров
6.class tuple<T, Ts...> : public tuple<Ts...> {
7. public:
8. tuple(T t, Ts... ts) : tuple<Ts...>(ts...), value(t) {}
9.// Ссылка на родителя
10. tuple<Ts...> &next = static_cast<tuple<Ts...>&>(*this);
11.// Последний параметр
12. T value;
13.};
Что	
  внутри?
1.class tuple<double, uint64_t, const char*> : public tuple<uint64_t, const char*>
{
2. double value;
3.}
4.class tuple<uint64_t, const char*> : public tuple<const char*> {
5. uint64_t value;
6.}
7.class tuple<const char*> : public tuple {
8. const char* value;
9.}
10.class tuple {
11.}
std::enable_if
1. // Шаблон
2. template<bool, typename _Tp = void>
3. struct enable_if { };
4. // Специализация шаблона, в случае если параметр - истина
5. template<typename _Tp>
6. struct enable_if<true, _Tp>{
7. typedef _Tp type;
8.};
Вспомогательный	
  тип
1.// специальная структура для определения типа конкретного элемента в
tuple
2.template <size_t, class> struct elem_type_holder;
3.// без параметра - это тип базового класса
4.template <class T, class... Ts> struct elem_type_holder<0, tuple<T,
Ts...>> {
5. typedef T type; // тип
6.};
7.// это тип k-го класса в цепочке наследования
8.template <size_t k, class T, class... Ts> struct elem_type_holder<k,
tuple<T, Ts...>> {
9.typedef typename elem_type_holder<k - 1, tuple<Ts...>>::type type;
10.};
Шаблонная	
  функция	
  get
Example57_VariadicTemplate2Full
1.// шаблон функции get для получения параметра (данная специализация работает только при
index==0)
2.template <size_t index,class ...Ts>
3.typename std::enable_if<index == 0,
4. typename elem_type_holder<0, tuple<Ts...>>::type&>::type
5.get(tuple<Ts...>& t){
6. return t.value;
7.}
8.// шаблон функции get для получения параметра (данная специализация работает только при
index!=0)
9.template <size_t index,class T,class ...Ts>
10.typename std::enable_if<index != 0,
11. typename elem_type_holder<index, tuple<T,Ts...>>::type&>::type
12.get(tuple<T,Ts...>& t){
13. tuple<Ts...> &base = t.next;
14. return get<index-1>(base);
15.}
CRTP	
  (Curiously	
  Recurring	
  Template	
  Pattern)
Example60_CRTP
template <class T>
class base{};
class derived : public
base<derived> {};
Такая	
  конструкция	
  делает	
  возможным	
  
обращение	
  к	
  производному	
  классу	
  из	
  
базового!
Множественное	
  наследование	
  в	
  шаблонах
Example58_VariadicTemplate3
1.template <typename... BaseClasses>
2.class Printer : public BaseClasses... {
3.public:
4.Printer(BaseClasses&&... base_classes) :
BaseClasses(base_classes)...
5.{
6.}
7.};
Шаблоны	
  в	
  качестве	
  параметров	
  шаблонов
Example59_TemplateParameter
• Шаблон	
  можно	
  указать	
  в	
  
качестве	
  параметра	
  шаблона!
• Все	
  типы,	
  которые	
  
используются	
  при	
  
конструировании	
  нового	
  типа	
  с	
  
помощью	
  шаблона	
  – должны	
  
быть	
  его	
  параметрами.
template <class T> class Payload
{
…
};
template <template <class> class
PL, class T> class Printer
{
…
};
Printer<Payload, int> printer;
Что	
  нового	
  в	
  C++:	
  auto
Example62_Auto
В	
  С++11 auto позволяет	
  не	
  указывать	
  тип	
  переменной	
  явно,	
  говоря	
  компилятору,	
  чтобы	
  он	
  
сам	
  определил	
  фактический	
  тип	
  переменной,	
  на	
  основе	
  типа	
  инициализируемого	
  
значения.	
  Это	
  может	
  использоваться	
  при	
  объявлении	
  переменных	
  в	
  различных	
  областях	
  
видимости,	
  как,	
  например,	
  пространство	
  имен,	
  блоки,	
  инициализация	
  в	
  цикле	
  и	
  т.п.
auto	
  i =	
  42;	
  	
  	
  	
  	
  	
  	
  	
  //	
  i -­‐ int
auto	
  l	
  =	
  42LL;	
  	
  	
  	
  	
  	
  //	
  l	
  -­‐ long	
  long
auto	
  p	
  =	
  new	
  foo();	
  //	
  p	
  -­‐ foo*
Использование auto позволяет	
  сократить	
  код	
  (если,	
  конечно,	
  тип	
  не int,	
  который	
  на	
  одну	
  
букву	
  меньше).
Не	
  может	
  использоваться	
  в	
  объявлении	
  параметров	
  функции	
  или	
  класса;
Протечка	
  абстракции
Неудобной	
  составляющей	
  работы	
  с	
  коллекциями	
  
объектов	
  родительского	
  типа	
  является	
  необходимость	
  
приведения	
  родительского	
  типа	
  к	
  типу-­‐наследнику	
  (для	
  
выполнения	
  необходимых	
  операций	
  над	
  элементом	
  
коллекции).	
  Т.е.	
  мы	
  жертвуем	
  статическим	
  контролем	
  
типов.
Протеска	
  абстракции	
  номер	
  1
Example66_AbstractionLeak1
1. class Figure{
2. public:
3. virtual double Square()=0;};
4. class Circle : public Figure{
5. public:
6. double Square() override{
7. return 3.14*3.14*R;};};
8. class Sphere : public Circle{
9. public:
10. double Volume() {
11. return 3.14*3.14*3.14*R; };
12. };
// abstraction leak
for(Figure *figure:array)
{
Sphere *sphere = dynamic_cast<Sphere*> (figure);
if(sphere!=nullptr)
std::cout << "Volume:"
<< sphere->Volume()
<< std::endl;
}
Протечка	
  абстракции	
  2
Example66_AbstractionLeak2
1.class Figure{
2.public:
3. virtual double Square()=0;
4. virtual double Volume() { return 0.0;};
5. virtual ~Figure() {};
6.};
7. Figure* array[]={new Circle(1),new Circle (2),new Sphere(1)};
8. // ISP (Interface Segregation Principle) fail
9. for(Figure *figure:array) std::cout << "Square:" << figure->Square() << std::endl;
10. for(Figure *figure:array) std::cout << "Volume:" << figure->Volume() << std::endl;
Используем	
  tuple
Example68_AbstractionLeak3
1. tuple<Circle,Circle,Sphere,Sphere>
2. t(Circle(1),Circle(2),Sphere(1),Sphere(2));
3.// в параметры get<size_t> можно подставить только константу
4. std::cout << "Square:" << get<0>(t).Square() << std::endl;
5. std::cout << "Volume:" << get<3>(t).Volume() << std::endl;

More Related Content

What's hot

Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
Sergey Platonov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
Pavel Tsukanov
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
Igor Shkulipa
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Sergey Platonov
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
corehard_by
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
Roman Orlov
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
Roman Brovko
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
Dima Dzuba
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Sergey Platonov
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.
Roman Brovko
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
corehard_by
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.
Roman Brovko
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Roman Brovko
 
Лекция 10. Классы 2.
Лекция 10. Классы 2.Лекция 10. Классы 2.
Лекция 10. Классы 2.
Roman Brovko
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
mcroitor
 

What's hot (19)

Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
JRebel
JRebelJRebel
JRebel
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Bytecode
BytecodeBytecode
Bytecode
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
 
Лекция 10. Классы 2.
Лекция 10. Классы 2.Лекция 10. Классы 2.
Лекция 10. Классы 2.
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 

Similar to Объектно-ориентированное программирование. Лекция 7 и 8.

углубленное программирование на C++. лекция no.5 [4.0]
углубленное программирование на C++. лекция no.5 [4.0]углубленное программирование на C++. лекция no.5 [4.0]
углубленное программирование на C++. лекция no.5 [4.0]Technopark
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5Technopark
 
12 - Web-технологии. Django модели
12 - Web-технологии. Django модели12 - Web-технологии. Django модели
12 - Web-технологии. Django модели
Roman Brovko
 
6.4 Ещё о шаблонах
6.4 Ещё о шаблонах6.4 Ещё о шаблонах
6.4 Ещё о шаблонах
DEVTYPE
 
Лекция #7. Django ORM
Лекция #7. Django ORMЛекция #7. Django ORM
Лекция #7. Django ORM
Яковенко Кирилл
 
C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.
Igor Shkulipa
 
6.3 Специализация шаблонов
6.3 Специализация шаблонов6.3 Специализация шаблонов
6.3 Специализация шаблонов
DEVTYPE
 
Master class bars group ext js4
Master class bars group   ext js4Master class bars group   ext js4
Master class bars group ext js4Radik Fattakhov
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6Technopark
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.
Roman Brovko
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
MoscowDjango
 
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
corehard_by
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
Alexander Byndyu
 
Python: Модули и пакеты
Python: Модули и пакетыPython: Модули и пакеты
Python: Модули и пакеты
Theoretical mechanics department
 
C++ осень 2012 лекция 3
C++ осень 2012 лекция 3C++ осень 2012 лекция 3
C++ осень 2012 лекция 3Technopark
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.
Igor Shkulipa
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.
Igor Shkulipa
 

Similar to Объектно-ориентированное программирование. Лекция 7 и 8. (20)

углубленное программирование на C++. лекция no.5 [4.0]
углубленное программирование на C++. лекция no.5 [4.0]углубленное программирование на C++. лекция no.5 [4.0]
углубленное программирование на C++. лекция no.5 [4.0]
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5
 
12 - Web-технологии. Django модели
12 - Web-технологии. Django модели12 - Web-технологии. Django модели
12 - Web-технологии. Django модели
 
6.4 Ещё о шаблонах
6.4 Ещё о шаблонах6.4 Ещё о шаблонах
6.4 Ещё о шаблонах
 
Лекция #7. Django ORM
Лекция #7. Django ORMЛекция #7. Django ORM
Лекция #7. Django ORM
 
C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.
 
6.3 Специализация шаблонов
6.3 Специализация шаблонов6.3 Специализация шаблонов
6.3 Специализация шаблонов
 
Master class bars group ext js4
Master class bars group   ext js4Master class bars group   ext js4
Master class bars group ext js4
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
 
Python: Модули и пакеты
Python: Модули и пакетыPython: Модули и пакеты
Python: Модули и пакеты
 
Zend Framework и Doctrine
Zend Framework и DoctrineZend Framework и Doctrine
Zend Framework и Doctrine
 
C++ осень 2012 лекция 3
C++ осень 2012 лекция 3C++ осень 2012 лекция 3
C++ осень 2012 лекция 3
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.
 
лабраб 7
лабраб 7лабраб 7
лабраб 7
 

More from Dima Dzuba

Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16
Dima Dzuba
 
Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14
Dima Dzuba
 
Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12
Dima Dzuba
 
Requirement modelling in software creation process
Requirement modelling in software creation processRequirement modelling in software creation process
Requirement modelling in software creation process
Dima Dzuba
 
Модифицируемость программных систем
Модифицируемость программных системМодифицируемость программных систем
Модифицируемость программных систем
Dima Dzuba
 
Производительность программных систем
Производительность программных системПроизводительность программных систем
Производительность программных систем
Dima Dzuba
 
Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1
Dima Dzuba
 
МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7
Dima Dzuba
 
Решение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системРешение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных систем
Dima Dzuba
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4stsDima Dzuba
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Dima Dzuba
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Dima Dzuba
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Dima Dzuba
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Dima Dzuba
 

More from Dima Dzuba (20)

Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16Объектно-ориентированное программирование. Лекции 15 и 16
Объектно-ориентированное программирование. Лекции 15 и 16
 
Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14Объектно-ориентированное программирование. Лекции 13 и 14
Объектно-ориентированное программирование. Лекции 13 и 14
 
Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12Объектно-ориентированное программирование. Лекции 11 и 12
Объектно-ориентированное программирование. Лекции 11 и 12
 
Requirement modelling in software creation process
Requirement modelling in software creation processRequirement modelling in software creation process
Requirement modelling in software creation process
 
Модифицируемость программных систем
Модифицируемость программных системМодифицируемость программных систем
Модифицируемость программных систем
 
Производительность программных систем
Производительность программных системПроизводительность программных систем
Производительность программных систем
 
Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01Проектирование Программных Систем. Лекция 01
Проектирование Программных Систем. Лекция 01
 
МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6МАИ, Сети ЭВМ, Лекция №6
МАИ, Сети ЭВМ, Лекция №6
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5
 
МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4МАИ, Сети ЭВМ, Лекция №4
МАИ, Сети ЭВМ, Лекция №4
 
МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3МАИ, Сети ЭВМ, Лекция №3
МАИ, Сети ЭВМ, Лекция №3
 
МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2МАИ, Сети ЭВМ, Лекция №2
МАИ, Сети ЭВМ, Лекция №2
 
МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1МАИ, Сети ЭВМ, Лекция №1
МАИ, Сети ЭВМ, Лекция №1
 
МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7МАИ, Сети ЭВМ, Лекция №7
МАИ, Сети ЭВМ, Лекция №7
 
Решение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных системРешение конфликтов в процессе проектирования сложных систем
Решение конфликтов в процессе проектирования сложных систем
 
Arch intro4sts
Arch intro4stsArch intro4sts
Arch intro4sts
 
Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10Проектирование программных систем. Занятие 10
Проектирование программных систем. Занятие 10
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9
 
Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8Проектирование программных систем. Занятие 8
Проектирование программных систем. Занятие 8
 
Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7Проектирование программных систем. Занятие 7
Проектирование программных систем. Занятие 7
 

Объектно-ориентированное программирование. Лекция 7 и 8.

  • 2. Два  вида  многократного   использования  кода Наследование • Создаем  структуру  для  работы  с   «базовым  классом» • Создаем  классы-­‐наследники  на  каждый   случай. Шаблоны • Описываем  «стратегию  работы»  с   «неопределенным»  классом. • Компилятор  в  момент  создание  класса  по   шаблону,  сам  создает  нужный  «код»  для   конкретного  класса.
  • 3. Template  это  … • Шаблон  – это  параметрическая  функция  или  класс. • Параметром  может  являться  как  значение  переменной  (как  в   обычных  функциях)  так  и  тип  данных. • Параметры  подставляются  на  этапе  компиляции  программы. • Подставляя  параметры  в  шаблон  – мы  конструируем  новый  тип   данных  (или  функцию,  если  это  шаблон  функции)  
  • 4. Простой  шаблон Example50_Template template <class T> class Print { public: Print(T value) { std::cout << "Value:" << value << std::endl; }; }; Перед  описанием  класса  ставим  ключевое   слово  template  <class  T> T  – используем  вместо  имени  класса,   который  будет  заменяться  при  создании   конкретного  экземпляра  класса. Print – это  шаблон Print<int> -­‐ это  класс,   сконструированный  по  шаблону
  • 5. Несколько  параметров  и  шаблоны-­‐функции Example51_MultiTemplate Параметры  указываются  через  запятую: template <class A, class B> class Sum { …} Оператор,  принимающий  в  качестве  параметра  – шаблон  с   параметрами: template <class A, class B> std::ostream& operator<<(std::ostream & os, Sum<A, B> &sum)
  • 6. Параметры  – переменные Example52_ComplexParameters 1.template <class TYPE, TYPE def_value, size_t SIZE = 10 > class Array { 2.protected: 3. TYPE _array[SIZE]; 4.public: 5. Array() { 6. for (int i = 0; i < SIZE; i++) { 7. _array[i] = def_value; 8. } 9. } 10. const size_t size() { 11. return SIZE; 12. } 13. const TYPE operator[](size_t index) { 14. if ((index >= 0) && (index < SIZE)) return _array[index]; 15. else throw BadIndexException(index, SIZE); 16. } 17.};
  • 7. Специализация  шаблонов Example53_TemplateSpecialization template <class T> class mycontainer { // … }; template <> class mycontainer <char> { // .. }; Иногда  бывает  необходимость  сделать   специальную  реализацию  шаблона  для   какого-­‐либо  типа. В  этом  случае,  можно  описать  отдельную   реализацию  класса,  дополнив  его  новыми   методами  или  переопределив  реализацию   существующих.
  • 8. Можно  специализировать  только  часть   параметров Example54_TemplateSpecialization2 template <class A, class B, class C> class Sum { … } template <class A, class B> class Sum<A, B, const char*> { … } При  частичной  специализации  у  шаблона   становится  меньше  параметров  (какие-­‐то   мы  уже  указали  явно). Частичная  специализация  работает  только  с   классами  (с  функциями  не  работает).
  • 9. Вычисляем  факториал Example54_Factorial 1.// факториал с помощью функций 2.template <uint64_t value> uint64_t Factorial(){ 3. return Factorial<value-1>()*value; 4.} 5.template <> uint64_t Factorial<0>(){ 6. return 1; 7.} 8.// факториал с помощью классов 9.template<uint64_t n>class fact{ 10. public: 11. static const uint64_t value = fact<n-1>::value * n; 12.}; 13. template<>class fact<0>{ 14. public: 15. static const uint64_t value = 1; 16.};
  • 10. Templates две  модели 1.  Наиболее  популярный  подход  -­‐ модель   включения(inclusion model),  определения   шаблонов  полностью  размещаются  в   заголовочном  файле. 2.  Модель  явного  инстанцирования (explicit instantiation model),  как  правило  реализуется   директивой  явного  инстанцирования (explicit instantiation directive).
  • 11. Inclusion  model template<class T> class stack { T* v; T* p; int sz; public: stack(int s) { v = p = new T[sz=s]; } ~stack() { delete[] v; } void push(T a) { *p++ = a; } T pop() { return *--p; } int size() const { return p-v; } }; И  объявление  и  описание  шаблона   располагается  в  header  файле  (.h) Фактически,  при  любом   подключении  к  .cpp файлу  – это   будет  новый  шаблон  для   компилятора. Минус  такой  модели  в  том,  что   трудно  читать  код  (все  перемешано).
  • 12. explicit instantiation model Example55_ExplicitInstantiation template <class T> class MyStack { public: MyStack(void); }; template <class T> MyStack<T>::MyStack(void) { _size = 0; _current = NULL; } template class MyStack<class MyClass>;
  • 13. В  продолжение  примера 1. В  качестве  параметра  шаблона  можно  передавать  указатели  на  функции  (если  работать   не  с  указателями  – то  это  уже  будет  вызов  функции  J ) 2. В  примере  «параметр-­‐функция»  нам  понадобился  что  бы  удалять  указатели.  Если  бы   мы  в  коде  написали  «delete  old-­‐>item»  то  такой  код  не  скомпилировался  бы  для  класса   MyStack<MyClass>. 3. А  вот  для  MyStack<MyClass*>  -­‐ скомпилировался  бы.
  • 14. Шаблоны  с  переменным  числом   параметров Example56_VariadicTemplate template <class T> void print(const T& t) { std::cout << t << std::endl; } template <class First, class... Rest> void print(const First& first, const Rest&... rest) { print(rest...); } • В  C++  есть  возможность  сделать  шаблон  с   переменным  числом  параметров. • В  этом  случае  используется  «…»  для   указания  списка  параметров. • Работать  с  такими  шаблонами  можно  по   принципу  рекурсии.
  • 15. Variadic template  в  структурах  данных Example57_VariadicTemplate2 1.// Конец рекурсии 2.template <class... Ts> class tuple {}; 3.// Шаблон 4.template <class T, class... Ts> 5.// Класс наследник самого себя но с меньшим числом параметров 6.class tuple<T, Ts...> : public tuple<Ts...> { 7. public: 8. tuple(T t, Ts... ts) : tuple<Ts...>(ts...), value(t) {} 9.// Ссылка на родителя 10. tuple<Ts...> &next = static_cast<tuple<Ts...>&>(*this); 11.// Последний параметр 12. T value; 13.};
  • 16. Что  внутри? 1.class tuple<double, uint64_t, const char*> : public tuple<uint64_t, const char*> { 2. double value; 3.} 4.class tuple<uint64_t, const char*> : public tuple<const char*> { 5. uint64_t value; 6.} 7.class tuple<const char*> : public tuple { 8. const char* value; 9.} 10.class tuple { 11.}
  • 17. std::enable_if 1. // Шаблон 2. template<bool, typename _Tp = void> 3. struct enable_if { }; 4. // Специализация шаблона, в случае если параметр - истина 5. template<typename _Tp> 6. struct enable_if<true, _Tp>{ 7. typedef _Tp type; 8.};
  • 18. Вспомогательный  тип 1.// специальная структура для определения типа конкретного элемента в tuple 2.template <size_t, class> struct elem_type_holder; 3.// без параметра - это тип базового класса 4.template <class T, class... Ts> struct elem_type_holder<0, tuple<T, Ts...>> { 5. typedef T type; // тип 6.}; 7.// это тип k-го класса в цепочке наследования 8.template <size_t k, class T, class... Ts> struct elem_type_holder<k, tuple<T, Ts...>> { 9.typedef typename elem_type_holder<k - 1, tuple<Ts...>>::type type; 10.};
  • 19. Шаблонная  функция  get Example57_VariadicTemplate2Full 1.// шаблон функции get для получения параметра (данная специализация работает только при index==0) 2.template <size_t index,class ...Ts> 3.typename std::enable_if<index == 0, 4. typename elem_type_holder<0, tuple<Ts...>>::type&>::type 5.get(tuple<Ts...>& t){ 6. return t.value; 7.} 8.// шаблон функции get для получения параметра (данная специализация работает только при index!=0) 9.template <size_t index,class T,class ...Ts> 10.typename std::enable_if<index != 0, 11. typename elem_type_holder<index, tuple<T,Ts...>>::type&>::type 12.get(tuple<T,Ts...>& t){ 13. tuple<Ts...> &base = t.next; 14. return get<index-1>(base); 15.}
  • 20. CRTP  (Curiously  Recurring  Template  Pattern) Example60_CRTP template <class T> class base{}; class derived : public base<derived> {}; Такая  конструкция  делает  возможным   обращение  к  производному  классу  из   базового!
  • 21. Множественное  наследование  в  шаблонах Example58_VariadicTemplate3 1.template <typename... BaseClasses> 2.class Printer : public BaseClasses... { 3.public: 4.Printer(BaseClasses&&... base_classes) : BaseClasses(base_classes)... 5.{ 6.} 7.};
  • 22. Шаблоны  в  качестве  параметров  шаблонов Example59_TemplateParameter • Шаблон  можно  указать  в   качестве  параметра  шаблона! • Все  типы,  которые   используются  при   конструировании  нового  типа  с   помощью  шаблона  – должны   быть  его  параметрами. template <class T> class Payload { … }; template <template <class> class PL, class T> class Printer { … }; Printer<Payload, int> printer;
  • 23. Что  нового  в  C++:  auto Example62_Auto В  С++11 auto позволяет  не  указывать  тип  переменной  явно,  говоря  компилятору,  чтобы  он   сам  определил  фактический  тип  переменной,  на  основе  типа  инициализируемого   значения.  Это  может  использоваться  при  объявлении  переменных  в  различных  областях   видимости,  как,  например,  пространство  имен,  блоки,  инициализация  в  цикле  и  т.п. auto  i =  42;                //  i -­‐ int auto  l  =  42LL;            //  l  -­‐ long  long auto  p  =  new  foo();  //  p  -­‐ foo* Использование auto позволяет  сократить  код  (если,  конечно,  тип  не int,  который  на  одну   букву  меньше). Не  может  использоваться  в  объявлении  параметров  функции  или  класса;
  • 24. Протечка  абстракции Неудобной  составляющей  работы  с  коллекциями   объектов  родительского  типа  является  необходимость   приведения  родительского  типа  к  типу-­‐наследнику  (для   выполнения  необходимых  операций  над  элементом   коллекции).  Т.е.  мы  жертвуем  статическим  контролем   типов.
  • 25. Протеска  абстракции  номер  1 Example66_AbstractionLeak1 1. class Figure{ 2. public: 3. virtual double Square()=0;}; 4. class Circle : public Figure{ 5. public: 6. double Square() override{ 7. return 3.14*3.14*R;};}; 8. class Sphere : public Circle{ 9. public: 10. double Volume() { 11. return 3.14*3.14*3.14*R; }; 12. }; // abstraction leak for(Figure *figure:array) { Sphere *sphere = dynamic_cast<Sphere*> (figure); if(sphere!=nullptr) std::cout << "Volume:" << sphere->Volume() << std::endl; }
  • 26. Протечка  абстракции  2 Example66_AbstractionLeak2 1.class Figure{ 2.public: 3. virtual double Square()=0; 4. virtual double Volume() { return 0.0;}; 5. virtual ~Figure() {}; 6.}; 7. Figure* array[]={new Circle(1),new Circle (2),new Sphere(1)}; 8. // ISP (Interface Segregation Principle) fail 9. for(Figure *figure:array) std::cout << "Square:" << figure->Square() << std::endl; 10. for(Figure *figure:array) std::cout << "Volume:" << figure->Volume() << std::endl;
  • 27. Используем  tuple Example68_AbstractionLeak3 1. tuple<Circle,Circle,Sphere,Sphere> 2. t(Circle(1),Circle(2),Sphere(1),Sphere(2)); 3.// в параметры get<size_t> можно подставить только константу 4. std::cout << "Square:" << get<0>(t).Square() << std::endl; 5. std::cout << "Volume:" << get<3>(t).Volume() << std::endl;