SlideShare une entreprise Scribd logo
1  sur  63
1
2 
Статический и 
динамический 
полиморфизм в C++ 
Дмитрий Леванов 
Ведущий разработчик Крипта
3 
Крипта 
 Отвечает на вопрос «Кто?» 
 Определяет интересы по поведению в 
интернете 
 Используется для таргетинга рекламы 
 От др.-греч. κρυπτή — крытый подземный ход, 
тайник
4 
Как учили Крипту 
+ Логи 
Обучение Контроль 
Матрикснет
5 
Крипта
6 
Разработка Крипты 
 Много логов в разных форматах 
 Сложные цепочки обработки 
 Высокие требования к производительности 
 Много одинаковой похожей логики 
 Хочется делать всё однообразно
7 
Полиморфизм
8 
Полиморфизм 
 Способ поставить в соответствие некой 
грамматической конструкции контекстно- 
зависимую семантику 
или, по-русски: 
 Текст программы [почти] один и тот же, а 
смысл разный
9 
Виртуальный полиморфизм 
struct Base { 
virtual void do() { std::cout << “base”; } 
}; 
struct Derived : public Base { 
virtual void do() { std::cout << “derived”; } 
}; 
Base* b = new Derived(); 
b->do(); // derived 
 ООП-шненько 
 Типобезопасно 
 Работают фичи, зависящие от _vptr
Виртуальный полиморфизм: минусы 
 Медленный вызов методов 
 Надо поддерживать иерархию классов 
 Приходится иметь дело с T* или T& 
 Грабли с виртуальными методами 
 Статический метод не может быть виртуальным 
 Инвариантность параметров 
10
11 
Зачастую все сводится к… 
void for_each(const vector<int>& v, const Handler& h) { 
for (int i : v) { 
h.handle(i); 
} 
} 
//... 
vector<int> vect = {1,2,3}; 
MyHandler handler; 
for_each(vect, handler);
12 
То же самое, но лучше 
template<typename Handler> 
void for_each(const vector<int>& v, const Handler& h) { 
for (int i : v) { 
h.handle(i); 
} 
} 
//... 
vector<int> vect = {1,2,3}; 
MyHandler handler; 
for_each(vect, handler);
13 
Продолжаем улучшать 
template<typename Handler> 
void for_each(const vector<int>& v, const Handler& h) { 
for (int i : v) { 
h(i); 
} 
} 
//... 
vector<int> vect = {1,2,3}; 
MyHandler handler; 
for_each(vect, handler);
14 
Совсем хорошо 
template<typename Handler> 
void for_each(const vector<int>& v, const Handler& h) { 
for (int i : v) { 
h(i); 
} 
} 
//... 
vector<int> vect = {1,2,3}; 
for_each(vect, [](int i){ cout << i; });
15 
Или так 
template<typename Handler> 
void for_each(const vector<int>& v) { 
for (int i : v) { 
Handler::handle(i); 
} 
} 
//... 
vector<int> vect = {1,2,3}; 
MyHandler handler; 
for_each<MyHandler>(vect);
16 
Статический полиморфизм: плюсы 
 Типобезопасно 
 Быстрый вызов методов 
 Не надо наследоваться 
 Не надо иметь дело с указателями 
 Контрвариантность параметров 
 Можно использовать лямбды
Статический полиморфизм: минусы 
17 
 Нельзя положить в коллекцию 
 Сложно проверять правильность кода 
 Медленно компилируется 
 Может распухнуть бинарник 
 Нет поддержки концептов 
 Есть ограничения компилятора 
 Не во всех IDE правильно работает 
автокомплит
18 
Синтаксис иногда довольно 
странный… 
this->do();
19 
Синтаксис иногда довольно 
странный… 
this->do(); 
typename T::iter f(typename T::iter i);
20 
Синтаксис иногда довольно 
странный… 
this->do(); 
typename T::iter f(typename T::iter i); 
this->template do<T>(); // WTF???
21 
Замещение 
виртуального 
полиморфизма 
статическим
«Виртуальный» вызов без virtual 
a.k.a. Curiously Recurring Template Pattern 
22
«Виртуальный» вызов без virtual 
a.k.a. Curiously Recurring Template Pattern 
23 
template<typename Derived> 
class Base { 
void do() { 
Derived::do(); 
} 
};
«Виртуальный» вызов без virtual 
a.k.a. Curiously Recurring Template Pattern 
24 
template<typename Derived> 
class Base { 
void do() { 
Derived::do(); 
} 
}; 
class MyDerived : public Base<MyDerived> { 
void do() { std::cout << "my derived"; } 
};
«Виртуальный» вызов без virtual 
a.k.a. Curiously Recurring Template Pattern 
25 
template<typename Derived> 
class Base { 
void do() { 
Derived::do(); 
} 
}; 
class MyDerived : public Base<MyDerived> { 
void do() { std::cout << "my derived"; } 
}; 
Base<MyDerived>* b = new MyDerived(); 
b->do(); // my derived
«Виртуальный» вызов без virtual 
a.k.a. Curiously Recurring Template Pattern 
26 
template<typename Derived> 
class Base { 
void do() { 
static_cast<Derived*>(this)->do(); 
} 
}; 
class MyDerived : public Base<MyDerived> { 
void do() { std::cout << "my derived"; } 
}; 
Base<MyDerived>* b = new MyDerived(); 
b->do(); // my derived
27 
CRTP 
 Идеально подходит для шаблона 
проектирования «Template method» 
 «Виртуальный» метод может быть 
статическим 
 Работает в ~7 раз быстрее виртуальной 
версии
28 
Иногда без статического 
полиморфизма не 
обойтись
29 
Tag dispatching 
template <class InputIter, class Dist> 
void advance (InputIter& it, Dist n); 
template <class InputIter, class Dist> 
void advance(InputIter& i, Dist n) { 
while (n--) ++i; 
} 
template <class RndAcsIter, class Dist> 
void advance(RndAcsIter& i, Dist n) { 
i += n; 
}
30 
Tag dispatching 
template <class InputIter, class Dist> 
void advance (InputIter& it, Dist n); 
template <class InputIter, class Dist> 
void advance(InputIter& i, Dist n, input_iter_tag) { 
while (n--) ++i; 
} 
template <class RndAcsIter, class Dist> 
void advance(RndAcsIter& i, Dist n, rnd_acs_iter_tag) { 
i += n; 
}
31 
Tag dispatching 
template <class InputIter, class Dist> 
void advance (InputIter& it, Dist n) { 
typename iter_traits<InputIter>::iter_category cat; 
advance(i, n, cat); 
} 
template <class InputIter, class Dist> 
void advance(InputIter& i, Dist n, input_iter_tag) { 
while (n--) ++i; 
} 
template <class RndAcsIter, class Dist> 
void advance(RndAcsIter& i, Dist n, rnd_acs_iter_tag) { 
i += n; 
}
32 
Совмещаем концепции
33 
Задача 
 Например, мы пишем дебаггер 
 Есть множество объектов, не связанных 
какой-либо иерархией 
 Хотим сложить их в одну коллекцию, 
проитерироваться по ней, и сдампить объекты 
int x = 10; 
Foo bar; 
objects.add(x); 
objects.add(bar); 
for (const auto& obj : objects) { 
obj.dump(); 
}
34 
External polymorphism 
struct Dumpable { 
virtual void dump() const = 0; 
};
35 
External polymorphism 
struct Dumpable { 
virtual void dump() const = 0; 
}; 
template<typename T> 
class ConcreteDumpable<T> : public Dumpable { 
const T& value; 
public: 
ConcreteDumpable(const T& value) : value(value) {} 
virtual void dump() const { 
::dump(value); 
} 
};
36 
External polymorphism 
struct Dumpable { 
virtual void dump() const = 0; 
}; 
template<typename T> 
class ConcreteDumpable<T> : public Dumpable { 
const T& value; 
public: 
ConcreteDumpable(const T& value) : value(value) {} 
virtual void dump() const { 
::dump(value); 
} 
}; 
void dump(const Foo& foo) { 
foo.printToConsole(); 
}
37 
External polymorphism 
class Dumper { 
std::vector<Dumpable*> dumpables; 
public: 
template<typename T> 
void add(T& obj) { 
auto dumpable = new ConcreteDumpable<T>(obj); 
dumpables.push_back(dumpable); 
} 
void dumpAll() const { 
for (auto d : dumpables) { d->dump(); } 
} 
};
38 
External polymorphism 
class Dumper { 
std::vector<Dumpable*> dumpables; 
public: 
template<typename T> 
void add(T& obj) { 
auto dumpable = new ConcreteDumpable<T>(obj); 
dumpables.push_back(dumpable); 
} 
void dumpAll() const { 
for (auto d : dumpables) { d->dump(); } 
} 
} dumper; 
int x = 10; 
Foo bar; 
dumper.add(x); 
dumper.add(foo); 
dumper.dumpAll();
39 
External polymorphism 
 Симбиоз виртуального и статического 
полиморфизма 
 Для поддержки нового типа T надо добавить 
только ::dump(T) 
 Можно строить параллельные иерархии
40 
Новые возможности C++
Новые возможности C++11: лямбды 
41 
int x = 10; 
vector<int> v = { 1, 2, 3 }; 
for_each(v.begin(), v.end(), [x](int i){cout << i+x;});
Новые возможности C++11: лямбды 
42 
int x = 10; 
vector<int> v = { 1, 2, 3 }; 
for_each(v.begin(), v.end(), [x](int i){cout << i+x;}); 
class Lambda { 
int x; 
public: 
Lambda(int x) : x(x) {} 
void operator( )(int i) {cout << i+x;} 
}; 
for_each(Lambda());
Новые возможности C++14: лямбды 
43 
int x = 10; 
vector<int> v = { 1, 2, 3 }; 
for_each(v.begin(), v.end(), [x](auto i){cout << i+x;});
Новые возможности C++14: лямбды 
44 
int x = 10; 
vector<int> v = { 1, 2, 3 }; 
for_each(v.begin(), v.end(), [x](auto i){cout << i+x;}); 
class Lambda { 
int x; 
public: 
Lambda(int x) : x(x) {} 
template<typename T> 
void operator( )(T i) {cout << i+x;} 
};
45 
Новые возможности C++11: 
std::function 
using namespace std; 
void print(int i) { cout << i; } 
struct Print { 
void operator()(int i) {cout << i+x;} 
}
46 
Новые возможности C++11: 
std::function 
using namespace std; 
void print(int i) { cout << i; } 
struct Print { 
void operator()(int i) {cout << i+x;} 
} 
function<void(int)> p1 = print; 
function<void(int)> p1 = Print; 
function<void(int)> p1 = [](int i) {cout << i+x;};
47 
Новые возможности C++11: 
std::function 
using namespace std; 
void print(int i) { cout << i; } 
struct Print { 
void operator()(int i) {cout << i+x;} 
} 
function<void(int)> p1 = print; 
function<void(int)> p1 = Print; 
function<void(int)> p1 = [](int i) {cout << i+x;};
48 
Новые возможности C++11: 
std::function 
 Медленные (~10 раз медленнее шаблонной 
функции) 
 Обеспечивают поддержку концептов 
 Позволяют сохранить исполняемые объекты
49 
Новые возможности C++11: 
std::function 
 Медленные (~10 раз медленнее шаблонной 
функции) 
 Обеспечивают поддержку концептов 
 Позволяют сохранить исполняемые объекты 
 Не замена шаблонам и виртуальным методам!
50 
Пример из жизни
51 
Исходные условия 
id=1234 t time=2014.26.09 19:00 
struct RecordBase { 
void Load(const string& str); 
string GetValue(const string& key) const; 
void SetValue(const string& key, const string& value); 
};
52 
Версия 1.0 
struct EventRecord : RecordBase { 
int GetId() const { 
string str = GetValue("id"); 
// Parse id from str 
return id; 
} 
void SetId(int id) { 
// Serialize id to str 
SetValue("id", str); 
} 
time_t GetTs() const { 
string str = GetValue("time"); 
// Parse ts from str 
return ts; 
} 
void SetTs(time_t ts) { 
// Serialize ts to str 
SetValue("date", str); 
} 
};
53 
Версия 1.1 
struct EventRecord : RecordBase { 
int GetId() const { 
return ::FromString(GetValue("id")); 
} 
void SetId(int id) { 
SetValue("id", ::ToString(id)); 
} 
int GetTs() const { 
return ::FromString(GetValue("time")); 
} 
void SetTs(time_t ts) { 
SetValue("time", ::ToString(ts)); 
} 
};
54 
Уходим из :: 
template<typename T> 
struct Serializer { 
static T FromString(const string& str) { 
return ::FromString(str); 
} 
static string FromString(const T& value) { 
return ::ToString(value); 
} 
};
55 
Инкапсулируем логику RecordBase 
struct RecordBase { 
string GetValue(const string& key) const; 
void SetValue(const string& key, const string& value); 
template<typename Szr = Serializer, typename T> 
T Get(const string& key) const { 
return Szr::FromString(GetValue(key)); 
} 
template<typename Szr = Serializer, typename T> 
void Set(const string& key, const T& value) { 
SetValue(key, Szr::ToString(ts)); 
} 
};
56 
Упрощаем EventRecord 
struct EventRecord : RecordBase { 
int GetId() const { 
return Get<>("id"); 
} 
void SetId(int id) { 
Set<>("id", id); 
} 
int GetTs() const { 
return Get<DateSerializer>("time"); 
} 
void SetTs(time_t ts) { 
Set<DateSerializer>("time", ts); 
} 
};
57 
Еще больше инкапсуляции 
template<typename T, typename Szr = Serializer> 
class Property { 
RecordBase* record; 
string key; 
public: 
Property(RecordBase* record, const string& key) 
: record(record), key(key) {} 
T Get() const { 
return Szr::FromString(record->GetValue(key)); 
} 
void SetTs(const T& value) { 
record->SetValue(key, Szr::ToString(value)); 
} 
};
58 
Итоговая версия 
struct EventRecord : RecordBase { 
Property<int> Id; 
Property<time_t, DateSerializer> Ts; 
EventRecord() : Id("id"), Ts("time") {} 
}; 
EventRecord record; 
record.Id.Set(123); 
time_t ts = record.Ts.Get();
59 
Итоги
60 
Топ фич (субъективный) 
1. Обычный метод/функция 
2. Шаблонный метод/функция (+лямбды) 
3. Шаблонный класс (+CRTP) 
4. Виртуальный метод 
5. Внешний полиморфизм 
6. std::function
61 
Топ фич (субъективный) 
1. Обычный метод/функция 
2. Шаблонный метод/функция (+лямбды) 
3. Шаблонный класс (+CRTP) 
4. Виртуальный метод 
5. Внешний полиморфизм 
6. std::function
62 
Спасибо за внимание! 
Дмитрий Леванов 
Ведущий разработчик Крипта 
levanov@yandex-team.ru
63 
Источники 
1. http://www.inteks.ru/OOAD/P-Cources.OOAD.part1.pdf 
2. http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 
3. http://www.cs.wustl.edu/~schmidt/PDF/External-Polymorphism.pdf 
4. http://www.generic-programming.org/languages/cpp/techniques.php 
5. http://eli.thegreenplace.net/2013/12/05/the-cost-of-dynamic-virtual-calls- 
vs-static-crtp-dispatch-in-c/

Contenu connexe

Tendances

Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Dima Dzuba
 
тема 2.операторы.линейный алгоритм
тема 2.операторы.линейный алгоритмтема 2.операторы.линейный алгоритм
тема 2.операторы.линейный алгоритм
dasha2012
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli types
mcroitor
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScript
Dmytro Mindra
 

Tendances (20)

Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
тема 2.операторы.линейный алгоритм
тема 2.операторы.линейный алгоритмтема 2.операторы.линейный алгоритм
тема 2.операторы.линейный алгоритм
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
Python
PythonPython
Python
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli types
 
3.3 Конструкторы и деструкторы
3.3 Конструкторы и деструкторы3.3 Конструкторы и деструкторы
3.3 Конструкторы и деструкторы
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScript
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Программирование на языке C Sharp (СИ решетка)
Программирование на языке C Sharp (СИ решетка)Программирование на языке C Sharp (СИ решетка)
Программирование на языке C Sharp (СИ решетка)
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10
 

Similaire à Статический и динамический полиморфизм в C++, Дмитрий Леванов

Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Mikhail Kurnosov
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
guestfc8ae0
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
Andrey Karpov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
Andrey Karpov
 

Similaire à Статический и динамический полиморфизм в C++, Дмитрий Леванов (20)

Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x Introduction
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?
 
лекция 3
лекция 3лекция 3
лекция 3
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование
 
Erlang
ErlangErlang
Erlang
 
Кирилл Харьков
Кирилл ХарьковКирилл Харьков
Кирилл Харьков
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
Tricky Java Generics
Tricky Java GenericsTricky Java Generics
Tricky Java Generics
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
"Погружение в Robolectric" Дмитрий Костырев (Avito)
"Погружение в Robolectric"  Дмитрий Костырев (Avito)"Погружение в Robolectric"  Дмитрий Костырев (Avito)
"Погружение в Robolectric" Дмитрий Костырев (Avito)
 

Plus de Yandex

Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Yandex
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Yandex
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Yandex
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Yandex
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Yandex
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Yandex
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Yandex
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Yandex
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Yandex
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Yandex
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Yandex
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Yandex
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Yandex
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Yandex
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Yandex
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Yandex
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Yandex
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Yandex
 

Plus de Yandex (20)

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 

Dernier

Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
Хроники кибер-безопасника
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Ирония безопасности
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
Хроники кибер-безопасника
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
Хроники кибер-безопасника
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
Хроники кибер-безопасника
 
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
Ирония безопасности
 

Dernier (9)

Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
 
MS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdfMS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdf
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
 
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
 
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdfMalware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
 
Ransomware_Q3 2023. The report [RU].pdf
Ransomware_Q3 2023.  The report [RU].pdfRansomware_Q3 2023.  The report [RU].pdf
Ransomware_Q3 2023. The report [RU].pdf
 

Статический и динамический полиморфизм в C++, Дмитрий Леванов

  • 1. 1
  • 2. 2 Статический и динамический полиморфизм в C++ Дмитрий Леванов Ведущий разработчик Крипта
  • 3. 3 Крипта  Отвечает на вопрос «Кто?»  Определяет интересы по поведению в интернете  Используется для таргетинга рекламы  От др.-греч. κρυπτή — крытый подземный ход, тайник
  • 4. 4 Как учили Крипту + Логи Обучение Контроль Матрикснет
  • 6. 6 Разработка Крипты  Много логов в разных форматах  Сложные цепочки обработки  Высокие требования к производительности  Много одинаковой похожей логики  Хочется делать всё однообразно
  • 8. 8 Полиморфизм  Способ поставить в соответствие некой грамматической конструкции контекстно- зависимую семантику или, по-русски:  Текст программы [почти] один и тот же, а смысл разный
  • 9. 9 Виртуальный полиморфизм struct Base { virtual void do() { std::cout << “base”; } }; struct Derived : public Base { virtual void do() { std::cout << “derived”; } }; Base* b = new Derived(); b->do(); // derived  ООП-шненько  Типобезопасно  Работают фичи, зависящие от _vptr
  • 10. Виртуальный полиморфизм: минусы  Медленный вызов методов  Надо поддерживать иерархию классов  Приходится иметь дело с T* или T&  Грабли с виртуальными методами  Статический метод не может быть виртуальным  Инвариантность параметров 10
  • 11. 11 Зачастую все сводится к… void for_each(const vector<int>& v, const Handler& h) { for (int i : v) { h.handle(i); } } //... vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 12. 12 То же самое, но лучше template<typename Handler> void for_each(const vector<int>& v, const Handler& h) { for (int i : v) { h.handle(i); } } //... vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 13. 13 Продолжаем улучшать template<typename Handler> void for_each(const vector<int>& v, const Handler& h) { for (int i : v) { h(i); } } //... vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 14. 14 Совсем хорошо template<typename Handler> void for_each(const vector<int>& v, const Handler& h) { for (int i : v) { h(i); } } //... vector<int> vect = {1,2,3}; for_each(vect, [](int i){ cout << i; });
  • 15. 15 Или так template<typename Handler> void for_each(const vector<int>& v) { for (int i : v) { Handler::handle(i); } } //... vector<int> vect = {1,2,3}; MyHandler handler; for_each<MyHandler>(vect);
  • 16. 16 Статический полиморфизм: плюсы  Типобезопасно  Быстрый вызов методов  Не надо наследоваться  Не надо иметь дело с указателями  Контрвариантность параметров  Можно использовать лямбды
  • 17. Статический полиморфизм: минусы 17  Нельзя положить в коллекцию  Сложно проверять правильность кода  Медленно компилируется  Может распухнуть бинарник  Нет поддержки концептов  Есть ограничения компилятора  Не во всех IDE правильно работает автокомплит
  • 18. 18 Синтаксис иногда довольно странный… this->do();
  • 19. 19 Синтаксис иногда довольно странный… this->do(); typename T::iter f(typename T::iter i);
  • 20. 20 Синтаксис иногда довольно странный… this->do(); typename T::iter f(typename T::iter i); this->template do<T>(); // WTF???
  • 21. 21 Замещение виртуального полиморфизма статическим
  • 22. «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern 22
  • 23. «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern 23 template<typename Derived> class Base { void do() { Derived::do(); } };
  • 24. «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern 24 template<typename Derived> class Base { void do() { Derived::do(); } }; class MyDerived : public Base<MyDerived> { void do() { std::cout << "my derived"; } };
  • 25. «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern 25 template<typename Derived> class Base { void do() { Derived::do(); } }; class MyDerived : public Base<MyDerived> { void do() { std::cout << "my derived"; } }; Base<MyDerived>* b = new MyDerived(); b->do(); // my derived
  • 26. «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern 26 template<typename Derived> class Base { void do() { static_cast<Derived*>(this)->do(); } }; class MyDerived : public Base<MyDerived> { void do() { std::cout << "my derived"; } }; Base<MyDerived>* b = new MyDerived(); b->do(); // my derived
  • 27. 27 CRTP  Идеально подходит для шаблона проектирования «Template method»  «Виртуальный» метод может быть статическим  Работает в ~7 раз быстрее виртуальной версии
  • 28. 28 Иногда без статического полиморфизма не обойтись
  • 29. 29 Tag dispatching template <class InputIter, class Dist> void advance (InputIter& it, Dist n); template <class InputIter, class Dist> void advance(InputIter& i, Dist n) { while (n--) ++i; } template <class RndAcsIter, class Dist> void advance(RndAcsIter& i, Dist n) { i += n; }
  • 30. 30 Tag dispatching template <class InputIter, class Dist> void advance (InputIter& it, Dist n); template <class InputIter, class Dist> void advance(InputIter& i, Dist n, input_iter_tag) { while (n--) ++i; } template <class RndAcsIter, class Dist> void advance(RndAcsIter& i, Dist n, rnd_acs_iter_tag) { i += n; }
  • 31. 31 Tag dispatching template <class InputIter, class Dist> void advance (InputIter& it, Dist n) { typename iter_traits<InputIter>::iter_category cat; advance(i, n, cat); } template <class InputIter, class Dist> void advance(InputIter& i, Dist n, input_iter_tag) { while (n--) ++i; } template <class RndAcsIter, class Dist> void advance(RndAcsIter& i, Dist n, rnd_acs_iter_tag) { i += n; }
  • 33. 33 Задача  Например, мы пишем дебаггер  Есть множество объектов, не связанных какой-либо иерархией  Хотим сложить их в одну коллекцию, проитерироваться по ней, и сдампить объекты int x = 10; Foo bar; objects.add(x); objects.add(bar); for (const auto& obj : objects) { obj.dump(); }
  • 34. 34 External polymorphism struct Dumpable { virtual void dump() const = 0; };
  • 35. 35 External polymorphism struct Dumpable { virtual void dump() const = 0; }; template<typename T> class ConcreteDumpable<T> : public Dumpable { const T& value; public: ConcreteDumpable(const T& value) : value(value) {} virtual void dump() const { ::dump(value); } };
  • 36. 36 External polymorphism struct Dumpable { virtual void dump() const = 0; }; template<typename T> class ConcreteDumpable<T> : public Dumpable { const T& value; public: ConcreteDumpable(const T& value) : value(value) {} virtual void dump() const { ::dump(value); } }; void dump(const Foo& foo) { foo.printToConsole(); }
  • 37. 37 External polymorphism class Dumper { std::vector<Dumpable*> dumpables; public: template<typename T> void add(T& obj) { auto dumpable = new ConcreteDumpable<T>(obj); dumpables.push_back(dumpable); } void dumpAll() const { for (auto d : dumpables) { d->dump(); } } };
  • 38. 38 External polymorphism class Dumper { std::vector<Dumpable*> dumpables; public: template<typename T> void add(T& obj) { auto dumpable = new ConcreteDumpable<T>(obj); dumpables.push_back(dumpable); } void dumpAll() const { for (auto d : dumpables) { d->dump(); } } } dumper; int x = 10; Foo bar; dumper.add(x); dumper.add(foo); dumper.dumpAll();
  • 39. 39 External polymorphism  Симбиоз виртуального и статического полиморфизма  Для поддержки нового типа T надо добавить только ::dump(T)  Можно строить параллельные иерархии
  • 41. Новые возможности C++11: лямбды 41 int x = 10; vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](int i){cout << i+x;});
  • 42. Новые возможности C++11: лямбды 42 int x = 10; vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](int i){cout << i+x;}); class Lambda { int x; public: Lambda(int x) : x(x) {} void operator( )(int i) {cout << i+x;} }; for_each(Lambda());
  • 43. Новые возможности C++14: лямбды 43 int x = 10; vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](auto i){cout << i+x;});
  • 44. Новые возможности C++14: лямбды 44 int x = 10; vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](auto i){cout << i+x;}); class Lambda { int x; public: Lambda(int x) : x(x) {} template<typename T> void operator( )(T i) {cout << i+x;} };
  • 45. 45 Новые возможности C++11: std::function using namespace std; void print(int i) { cout << i; } struct Print { void operator()(int i) {cout << i+x;} }
  • 46. 46 Новые возможности C++11: std::function using namespace std; void print(int i) { cout << i; } struct Print { void operator()(int i) {cout << i+x;} } function<void(int)> p1 = print; function<void(int)> p1 = Print; function<void(int)> p1 = [](int i) {cout << i+x;};
  • 47. 47 Новые возможности C++11: std::function using namespace std; void print(int i) { cout << i; } struct Print { void operator()(int i) {cout << i+x;} } function<void(int)> p1 = print; function<void(int)> p1 = Print; function<void(int)> p1 = [](int i) {cout << i+x;};
  • 48. 48 Новые возможности C++11: std::function  Медленные (~10 раз медленнее шаблонной функции)  Обеспечивают поддержку концептов  Позволяют сохранить исполняемые объекты
  • 49. 49 Новые возможности C++11: std::function  Медленные (~10 раз медленнее шаблонной функции)  Обеспечивают поддержку концептов  Позволяют сохранить исполняемые объекты  Не замена шаблонам и виртуальным методам!
  • 50. 50 Пример из жизни
  • 51. 51 Исходные условия id=1234 t time=2014.26.09 19:00 struct RecordBase { void Load(const string& str); string GetValue(const string& key) const; void SetValue(const string& key, const string& value); };
  • 52. 52 Версия 1.0 struct EventRecord : RecordBase { int GetId() const { string str = GetValue("id"); // Parse id from str return id; } void SetId(int id) { // Serialize id to str SetValue("id", str); } time_t GetTs() const { string str = GetValue("time"); // Parse ts from str return ts; } void SetTs(time_t ts) { // Serialize ts to str SetValue("date", str); } };
  • 53. 53 Версия 1.1 struct EventRecord : RecordBase { int GetId() const { return ::FromString(GetValue("id")); } void SetId(int id) { SetValue("id", ::ToString(id)); } int GetTs() const { return ::FromString(GetValue("time")); } void SetTs(time_t ts) { SetValue("time", ::ToString(ts)); } };
  • 54. 54 Уходим из :: template<typename T> struct Serializer { static T FromString(const string& str) { return ::FromString(str); } static string FromString(const T& value) { return ::ToString(value); } };
  • 55. 55 Инкапсулируем логику RecordBase struct RecordBase { string GetValue(const string& key) const; void SetValue(const string& key, const string& value); template<typename Szr = Serializer, typename T> T Get(const string& key) const { return Szr::FromString(GetValue(key)); } template<typename Szr = Serializer, typename T> void Set(const string& key, const T& value) { SetValue(key, Szr::ToString(ts)); } };
  • 56. 56 Упрощаем EventRecord struct EventRecord : RecordBase { int GetId() const { return Get<>("id"); } void SetId(int id) { Set<>("id", id); } int GetTs() const { return Get<DateSerializer>("time"); } void SetTs(time_t ts) { Set<DateSerializer>("time", ts); } };
  • 57. 57 Еще больше инкапсуляции template<typename T, typename Szr = Serializer> class Property { RecordBase* record; string key; public: Property(RecordBase* record, const string& key) : record(record), key(key) {} T Get() const { return Szr::FromString(record->GetValue(key)); } void SetTs(const T& value) { record->SetValue(key, Szr::ToString(value)); } };
  • 58. 58 Итоговая версия struct EventRecord : RecordBase { Property<int> Id; Property<time_t, DateSerializer> Ts; EventRecord() : Id("id"), Ts("time") {} }; EventRecord record; record.Id.Set(123); time_t ts = record.Ts.Get();
  • 60. 60 Топ фич (субъективный) 1. Обычный метод/функция 2. Шаблонный метод/функция (+лямбды) 3. Шаблонный класс (+CRTP) 4. Виртуальный метод 5. Внешний полиморфизм 6. std::function
  • 61. 61 Топ фич (субъективный) 1. Обычный метод/функция 2. Шаблонный метод/функция (+лямбды) 3. Шаблонный класс (+CRTP) 4. Виртуальный метод 5. Внешний полиморфизм 6. std::function
  • 62. 62 Спасибо за внимание! Дмитрий Леванов Ведущий разработчик Крипта levanov@yandex-team.ru
  • 63. 63 Источники 1. http://www.inteks.ru/OOAD/P-Cources.OOAD.part1.pdf 2. http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 3. http://www.cs.wustl.edu/~schmidt/PDF/External-Polymorphism.pdf 4. http://www.generic-programming.org/languages/cpp/techniques.php 5. http://eli.thegreenplace.net/2013/12/05/the-cost-of-dynamic-virtual-calls- vs-static-crtp-dispatch-in-c/