SlideShare une entreprise Scribd logo
1  sur  66
1
2
Некоторые паттерны
реализации полиморфного
поведения в C++
Дмитрий Леванов
Ведущий разработчик Крипта
3
Крипта
4
Разработка Крипты
 Много логов в разных форматах
 Сложные цепочки обработки
 Высокие требования к производительности
 Много одинаковой похожей логики
 Хочется делать всё однообразно
5
Полиморфизм
6
Полиморфизм
 Способ поставить в соответствие некой
грамматической конструкции контекстно-
зависимую семантику
или, по-русски:
 Текст программы [почти] один и тот же, а
смысл разный
7
Шаблоны проектирования
 Abstract server/client
 Adapter
 Decorator
 Proxy
 Template method
 Command
 Strategy
 …
8
Виртуальный полиморфизм
struct Base {
virtual void do() { std::cout << “base”; }
};
struct Derived : public Base {
virtual void do() override {
std::cout << “derived”;
}
};
std::unique_ptr<Base> b(new Derived);
b->do(); // derived
 Явные интерфейсы
 Типобезопасно
 Работают фичи, зависящие от _vptr
9
Виртуальный полиморфизм: минусы
 Медленный вызов методов
 Расход памяти на объекты
 Требует наличия иерархии классов
 Приходится иметь дело с T* или T&
 Грабли с виртуальными методами
 Инвариантность параметров
10
Виртуальный полиморфизм: минусы
 Медленный вызов методов
 Расход памяти на объекты
 Требует наличия иерархии классов
 Приходится иметь дело с T* или T&
 Грабли с виртуальными методами
 Инвариантность параметров
 Во многих случаях это не критично
11
Виртуальный полиморфизм: минусы
 Медленный вызов методов
 Расход памяти на объекты
 Требует наличия иерархии классов
 Приходится иметь дело с T* или T&
 Грабли с виртуальными методами
 Инвариантность параметров
 Во многих случаях это не критично
 Но иногда может стать проблемой
12
Простой пример
13
Простой пример
struct Handler {
virtual void handle(int) = 0;
virtual ~Handler() {}
};
void for_each(const std::vector<int>& v, const Handler& h) {
for (int i : v) {
h.handle(i);
}
}
//...
std::vector<int> vect = {1,2,3};
MyHandler handler;
for_each(vect, handler);
14
То же самое, но лучше
template<typename Handler>
void for_each(const std::vector<int>& v, const Handler& h) {
for (int i : v) {
h.handle(i);
}
}
//...
std::vector<int> vect = {1,2,3};
MyHandler handler;
for_each(vect, handler);
15
То же самое, но лучше
template<typename Handler>
void for_each(const std::vector<int>& v, Handler& h) {
for (int i : v) {
h.handle(i);
}
}
struct Sum {
int sum = 0;
void handle(int i) { sum += i; }
};
std::vector<int> vect(1000000000);
Sum handler;
for_each(vect, handler);
16
То же самое, но лучше
template<typename Handler>
void for_each(const std::vector<int>& v, Handler& h) {
for (int i : v) {
h.handle(i);
}
}
struct Sum {
int sum = 0;
void handle(int i) { sum += i; }
};
std::vector<int> vect(1000000000);
Sum handler;
for_each(vect, handler);
Бесплатное ускорение x9.2 (-5 тактов на вызов)
17
То же самое, но лучше
template<typename Handler>
void for_each(const std::vector<int>& v, Handler& h) {
for (int i : v) {
h.handle(i);
}
}
struct PositivesSum {
int sum = 0;
void handle(int i) { if (i > 0) sum += i; }
};
std::vector<int> vect(1000000000);
PositivesSum handler;
for_each(vect, handler);
Бесплатное ускорение x2.8
18
Продолжаем улучшать
template<typename Handler>
void for_each(const std::vector<int>& v, const Handler& h) {
for (int i : v) {
h(i);
}
}
//...
std::vector<int> vect = {1,2,3};
MyHandler handler;
for_each(vect, handler);
19
Совсем хорошо
template<typename Handler>
void for_each(const std::vector<int>& v, const Handler& h) {
for (int i : v) {
h(i);
}
}
//...
std::vector<int> vect = {1,2,3};
for_each(vect, [](int i){std::cout << i; });
20
Или так
template<typename Handler>
void for_each(const std::vector<int>& v) {
for (int i : v) {
Handler::handle(i);
}
}
//...
std::vector<int> vect = {1,2,3};
for_each<MyHandler>(vect);
21
Статический полиморфизм: плюсы
 Нет накладных расходов на вызов методов
 Не надо наследоваться
 Не надо иметь дело с указателями
 Контрвариантность параметров
 Можно использовать лямбды
22
Статический полиморфизм: минусы
 Нельзя положить в коллекцию
 Сложно проверять правильность кода
 Медленно компилируется
 Может распухнуть бинарник
 Нельзя явно задать интерфейсы
 Мало помощи от IDE
23
Синтаксис иногда довольно
странный…
this->do();
24
Синтаксис иногда довольно
странный…
this->do();
typename T::iter f(typename T::iter i);
25
Синтаксис иногда довольно
странный…
this->do();
typename T::iter f(typename T::iter i);
this->template do<T>(); // WTF???
26
Curiously Recurring
Template Pattern
27
Template method
28
Template method
struct Game {
void play() {
while(!end()) {
makeTurn();
switchActivePlayer();
}
}
virtual bool end() = 0;
virtual void makeTurn() = 0;
virtual void switchActivePlayer() = 0;
virtual ~Game() {}
};
29
«Виртуальный» вызов без virtual
a.k.a. Curiously Recurring Template Pattern
30
«Виртуальный» вызов без virtual
a.k.a. Curiously Recurring Template Pattern
template<typename Derived>
class Game {
void end() {
static_cast<Derived*>(this)->end();
}
};
31
«Виртуальный» вызов без virtual
a.k.a. Curiously Recurring Template Pattern
template<typename Derived>
class Game {
void end() {
static_cast<Derived*>(this)->end();
}
};
class Chess : public Game<Chess> {
void end() {/*Check if king surrounded*/}
};
32
«Виртуальный» вызов без virtual
a.k.a. Curiously Recurring Template Pattern
template<typename Derived>
class Game {
void end() {
static_cast<Derived*>(this)->end();
}
};
class Chess : public Game<Chess> {
void end() {/*Check if king surrounded*/}
};
std::unique_ptr<Game<Chess>> game(new Chess);
game->play(); // calls Chess::end() inside
33
CRTP
 «Виртуальный» метод может быть
статическим
 Может работать в ~7 раз быстрее
виртуальной версии*
⃰ http://bit.ly/crtp_vs_virtual
34
Tag dispatching
35
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;
}
36
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;
}
37
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;
}
38
External polymorphism
39
Задача
 Пишем инструмент для отладки
 Есть множество объектов, не связанных
какой-либо иерархией
 Хотим сложить их в одну коллекцию,
проитерироваться по ней, и распечатать
содержимое объектов
int x = 10;
Foo bar;
MagicCollection objects;
objects.add(x);
objects.add(bar);
for (const auto& obj : objects) {
obj.dump();
}
40
External polymorphism
struct Dumpable {
virtual void dump() const = 0;
};
41
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 override {
::dump(value);
}
};
42
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 override {
::dump(value);
}
};
void dump(const Foo& foo) {
foo.printToConsole();
}
43
External polymorphism
class Dumper {
using DumpablePtr = std::unique_ptr<Dumpable>;
std::vector<DumpablePtr> dumpables;
public:
template<typename T>
void add(const T& obj) {
dumpables.push_back(
DumpablePtr(new ConcreteDumpable<T>(obj)));
}
void dumpAll() const {
for (const auto& d : dumpables) { d->dump(); }
}
};
44
External polymorphism
class Dumper {
using DumpablePtr = std::unique_ptr<Dumpable>;
std::vector<DumpablePtr> dumpables;
public:
template<typename T>
void add(const T& obj) {
dumpables.push_back(
DumpablePtr(new ConcreteDumpable<T>(obj)));
}
void dumpAll() const {
for (const auto& d : dumpables) { d->dump(); }
}
} dumper;
dumper.add(10);
dumper.add(Foo());
dumper.dumpAll();
45
External polymorphism
 Симбиоз виртуального и статического
полиморфизма
 Для поддержки нового типа T надо добавить
только ::dump(T)
 Можно строить параллельные иерархии
46
Новые возможности C++
47
Новые возможности C++11: лямбды
int x = 10;
std::vector<int> v = { 1, 2, 3 };
for_each(v.begin(), v.end(), [x](int i){cout << i+x;});
48
Новые возможности C++11: лямбды
int x = 10;
std::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) const {std::cout << i+x;}
};
for_each(v.begin(), v.end(), Lambda());
49
Новые возможности C++14: лямбды
int x = 10;
std::vector<int> v = { 1, 2, 3 };
for_each(v.begin(), v.end(), [x](auto i){cout << i+x;});
50
Новые возможности C++14: лямбды
int x = 10;
std::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) const {std::cout << i+x;}
};
51
Новые возможности C++11:
std::function
void print(int i) { std::cout << i; }
struct Print {
void operator()(int i) { std::cout << i+x; }
void print(int i) { std::cout << i+x; }
}
Print p;
std::function<void(int)> p1 = print;
std::function<void(int)> p2 = Print();
std::function<void(int)> p3 = std::bind(Print::print, p, _1);
std::function<void(int)> p4 = std::bind(Print::print, &p, _1);
std::function<void(const Print&, int)> p5 = &Print::print;
std::function<void(int)> p6 =
[](int i) { std::cout << i; };
52
Новые возможности C++11:
лямбды и std::function
auto lambda1 = []() {};
auto lambda2 = []() {};
lambda1(); // fast
std::function<void()> f = []() {};
f(); // slow
template<typename Handler>
void for_each(const std::vector<int>& v,
const Handler& h);
void for_each(const std::vector<int>& v,
std::function<void(int)> f);
53
Новые возможности C++11:
std::function
 Позволяют сохранить исполняемые объекты
(включая лямбды), в том числе в коллекцию
 Может быть медленной (~10 раз медленнее
шаблонной функции)
 Обеспечивает явную спецификацию
интерфейса
54
Пример из жизни
55
Исходные условия
id=1234 t time=2014.26.09 19:00
struct RecordBase {
void Load(const std::string& str);
std::string GetValue(const std::string& key) const;
void SetValue(const std::string& key,
const std::string& value);
};
 Хотим быстро создавать абстракции, позволяющие
типизированно работать с записями
56
Версия 1.0
struct EventRecord : RecordBase {
int GetId() const {
const auto& str = GetValue("id");
// Parse id from str
return id;
}
void SetId(int id) {
// Serialize id to str
SetValue("id", str);
}
time_t GetTs() const {
const auto& str = GetValue("time");
// Parse ts from str
return ts;
}
void SetTs(time_t ts) {
// Serialize ts to str
SetValue("date", str);
}
};
57
Версия 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));
}
};
58
Уходим из ::
struct Serializer {
template<typename T>
static T FromString(const std::string& str) {
return ::FromString<T>(str);
}
template<typename T>
static string ToString(const T& value) {
return ::ToString(value);
}
};
59
Инкапсулируем логику RecordBase
struct RecordBase {
std::string GetValue(const std::string& key) const;
void SetValue(const std::string& key,
const std::string& value);
template<typename T, typename Szr = Serializer>
T Get(const string& key) const {
return Szr::FromString<T>(GetValue(key));
}
template<typename Szr = Serializer, typename T>
void Set(const std::string& key, const T& value) {
SetValue(key, Szr::ToString(ts));
}
};
60
Упрощаем EventRecord
struct EventRecord : RecordBase {
int GetId() const {
return Get<int>("id");
}
void SetId(int id) {
Set<>("id", id);
}
int GetTs() const {
return Get<time_t, DateSerializer>("time");
}
void SetTs(time_t ts) {
Set<DateSerializer>("time", ts);
}
};
61
Еще больше инкапсуляции
template<typename T, typename Szr = Serializer>
class Property {
RecordBase* record;
std::string key;
public:
Property(RecordBase* record, const std::string& key)
: record(record), key(key) {}
T Get() const {
return Szr::FromString(record->GetValue(key));
}
void Set(const T& value) {
record->SetValue(key, Szr::ToString(value));
}
};
62
Итоговая версия
struct EventRecord : RecordBase {
Property<int> Id;
Property<time_t, DateSerializer> Ts;
EventRecord() : Id(this, "id"), Ts(this, "time") {}
};
EventRecord record;
record.Id.Set(123);
time_t ts = record.Ts.Get();
63
Заключение
64
Статический полиморфизм
 Большая гибкость
 Ограниченность в этапе компиляции
 Поощряется свежими стандартами
 Сложно писать библиотечный код
 Просто писать клиентский код
65
Спасибо за внимание!
Дмитрий Леванов
Ведущий разработчик Крипта
levanov@yandex-team.ru
66
Источники
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

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...Alexey Paznikov
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Dima Dzuba
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаSergey Platonov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиvictor-yastrebov
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Dima Dzuba
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...Alexey Paznikov
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 

Tendances (20)

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 

En vedette

Михаил Трошев — Инструменты веб-разработки
Михаил Трошев — Инструменты веб-разработкиМихаил Трошев — Инструменты веб-разработки
Михаил Трошев — Инструменты веб-разработкиYandex
 
Мобильная Яндекс.Почта — Дмитрий Александров
Мобильная Яндекс.Почта — Дмитрий АлександровМобильная Яндекс.Почта — Дмитрий Александров
Мобильная Яндекс.Почта — Дмитрий АлександровYandex
 
Коллективная разработка документации: от индивидуального авторства к командн...
 Коллективная разработка документации: от индивидуального авторства к командн... Коллективная разработка документации: от индивидуального авторства к командн...
Коллективная разработка документации: от индивидуального авторства к командн...Yandex
 
Жидков Игорь - Elliptics
Жидков Игорь - Elliptics   Жидков Игорь - Elliptics
Жидков Игорь - Elliptics Yandex
 
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, Риман
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, РиманАндрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, Риман
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, РиманYandex
 
Константин Горский - Дизайн
Константин Горский - ДизайнКонстантин Горский - Дизайн
Константин Горский - ДизайнYandex
 
Симаков Алексей - Системы управления кластерами
 Симаков Алексей - Системы управления кластерами   Симаков Алексей - Системы управления кластерами
Симаков Алексей - Системы управления кластерами Yandex
 
Антон Качалов - Популярно об IPMI и UEFI
Антон Качалов - Популярно об IPMI и UEFI Антон Качалов - Популярно об IPMI и UEFI
Антон Качалов - Популярно об IPMI и UEFI Yandex
 
Руководство по стилю документации: зачем и как, Татьяна Грачёва
Руководство по стилю документации: зачем и как, Татьяна ГрачёваРуководство по стилю документации: зачем и как, Татьяна Грачёва
Руководство по стилю документации: зачем и как, Татьяна ГрачёваYandex
 
Тропинка через минное поле — Леонычев Юрий
Тропинка через минное поле — Леонычев ЮрийТропинка через минное поле — Леонычев Юрий
Тропинка через минное поле — Леонычев ЮрийYandex
 
алексей тихонов
алексей тихоновалексей тихонов
алексей тихоновYandex
 
Дмитрий Васильев - Задачи ассиметричной криптографии
Дмитрий Васильев - Задачи ассиметричной криптографииДмитрий Васильев - Задачи ассиметричной криптографии
Дмитрий Васильев - Задачи ассиметричной криптографииYandex
 
вера сивакова
вера сиваковавера сивакова
вера сиваковаYandex
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...Yandex
 
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Yandex
 
Где прячутся мобильные вирусы — Григорий Земсков
Где прячутся мобильные вирусы — Григорий ЗемсковГде прячутся мобильные вирусы — Григорий Земсков
Где прячутся мобильные вирусы — Григорий ЗемсковYandex
 
Как делается Яндекс.Браузер — Михаил Лопаткин
Как делается Яндекс.Браузер — Михаил ЛопаткинКак делается Яндекс.Браузер — Михаил Лопаткин
Как делается Яндекс.Браузер — Михаил ЛопаткинYandex
 
Эталонное описание фильма на основе десятков дубликатов
Эталонное описание фильма на основе десятков дубликатовЭталонное описание фильма на основе десятков дубликатов
Эталонное описание фильма на основе десятков дубликатовYandex
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting Yandex
 

En vedette (20)

Михаил Трошев — Инструменты веб-разработки
Михаил Трошев — Инструменты веб-разработкиМихаил Трошев — Инструменты веб-разработки
Михаил Трошев — Инструменты веб-разработки
 
Мобильная Яндекс.Почта — Дмитрий Александров
Мобильная Яндекс.Почта — Дмитрий АлександровМобильная Яндекс.Почта — Дмитрий Александров
Мобильная Яндекс.Почта — Дмитрий Александров
 
Коллективная разработка документации: от индивидуального авторства к командн...
 Коллективная разработка документации: от индивидуального авторства к командн... Коллективная разработка документации: от индивидуального авторства к командн...
Коллективная разработка документации: от индивидуального авторства к командн...
 
Жидков Игорь - Elliptics
Жидков Игорь - Elliptics   Жидков Игорь - Elliptics
Жидков Игорь - Elliptics
 
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, Риман
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, РиманАндрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, Риман
Андрей Соболевский - Вокруг Базельской задачи: Бернулли, Эйлер, Риман
 
Константин Горский - Дизайн
Константин Горский - ДизайнКонстантин Горский - Дизайн
Константин Горский - Дизайн
 
Симаков Алексей - Системы управления кластерами
 Симаков Алексей - Системы управления кластерами   Симаков Алексей - Системы управления кластерами
Симаков Алексей - Системы управления кластерами
 
Антон Качалов - Популярно об IPMI и UEFI
Антон Качалов - Популярно об IPMI и UEFI Антон Качалов - Популярно об IPMI и UEFI
Антон Качалов - Популярно об IPMI и UEFI
 
Руководство по стилю документации: зачем и как, Татьяна Грачёва
Руководство по стилю документации: зачем и как, Татьяна ГрачёваРуководство по стилю документации: зачем и как, Татьяна Грачёва
Руководство по стилю документации: зачем и как, Татьяна Грачёва
 
Тропинка через минное поле — Леонычев Юрий
Тропинка через минное поле — Леонычев ЮрийТропинка через минное поле — Леонычев Юрий
Тропинка через минное поле — Леонычев Юрий
 
алексей тихонов
алексей тихоновалексей тихонов
алексей тихонов
 
Дмитрий Васильев - Задачи ассиметричной криптографии
Дмитрий Васильев - Задачи ассиметричной криптографииДмитрий Васильев - Задачи ассиметричной криптографии
Дмитрий Васильев - Задачи ассиметричной криптографии
 
вера сивакова
вера сиваковавера сивакова
вера сивакова
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...
Большие данные в физике элементарных частиц на примере LHCb - Guy Wilkinson, ...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Где прячутся мобильные вирусы — Григорий Земсков
Где прячутся мобильные вирусы — Григорий ЗемсковГде прячутся мобильные вирусы — Григорий Земсков
Где прячутся мобильные вирусы — Григорий Земсков
 
Как делается Яндекс.Браузер — Михаил Лопаткин
Как делается Яндекс.Браузер — Михаил ЛопаткинКак делается Яндекс.Браузер — Михаил Лопаткин
Как делается Яндекс.Браузер — Михаил Лопаткин
 
Эталонное описание фильма на основе десятков дубликатов
Эталонное описание фильма на основе десятков дубликатовЭталонное описание фильма на основе десятков дубликатов
Эталонное описание фильма на основе десятков дубликатов
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting
 

Similaire à Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов, Яндекс

Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...Alexey Paznikov
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x IntroductionFedor Vompe
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Проблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахПроблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахTatyanazaxarova
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)Ontico
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript Dmytro Mindra
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаPositive Hack Days
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptDmytro Mindra
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибкиAndrey Karpov
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 

Similaire à Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов, Яндекс (20)

Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
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
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Проблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерахПроблемы 64-битного кода на примерах
Проблемы 64-битного кода на примерах
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScript
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 

Plus de Yandex

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksYandex
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...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
 
Поиск списков в неструктурированных данных
Поиск списков в неструктурированных данныхПоиск списков в неструктурированных данных
Поиск списков в неструктурированных данных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айт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 
Поиск списков в неструктурированных данных
Поиск списков в неструктурированных данныхПоиск списков в неструктурированных данных
Поиск списков в неструктурированных данных
 

Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов, Яндекс

  • 1. 1
  • 2. 2 Некоторые паттерны реализации полиморфного поведения в C++ Дмитрий Леванов Ведущий разработчик Крипта
  • 4. 4 Разработка Крипты  Много логов в разных форматах  Сложные цепочки обработки  Высокие требования к производительности  Много одинаковой похожей логики  Хочется делать всё однообразно
  • 6. 6 Полиморфизм  Способ поставить в соответствие некой грамматической конструкции контекстно- зависимую семантику или, по-русски:  Текст программы [почти] один и тот же, а смысл разный
  • 7. 7 Шаблоны проектирования  Abstract server/client  Adapter  Decorator  Proxy  Template method  Command  Strategy  …
  • 8. 8 Виртуальный полиморфизм struct Base { virtual void do() { std::cout << “base”; } }; struct Derived : public Base { virtual void do() override { std::cout << “derived”; } }; std::unique_ptr<Base> b(new Derived); b->do(); // derived  Явные интерфейсы  Типобезопасно  Работают фичи, зависящие от _vptr
  • 9. 9 Виртуальный полиморфизм: минусы  Медленный вызов методов  Расход памяти на объекты  Требует наличия иерархии классов  Приходится иметь дело с T* или T&  Грабли с виртуальными методами  Инвариантность параметров
  • 10. 10 Виртуальный полиморфизм: минусы  Медленный вызов методов  Расход памяти на объекты  Требует наличия иерархии классов  Приходится иметь дело с T* или T&  Грабли с виртуальными методами  Инвариантность параметров  Во многих случаях это не критично
  • 11. 11 Виртуальный полиморфизм: минусы  Медленный вызов методов  Расход памяти на объекты  Требует наличия иерархии классов  Приходится иметь дело с T* или T&  Грабли с виртуальными методами  Инвариантность параметров  Во многих случаях это не критично  Но иногда может стать проблемой
  • 13. 13 Простой пример struct Handler { virtual void handle(int) = 0; virtual ~Handler() {} }; void for_each(const std::vector<int>& v, const Handler& h) { for (int i : v) { h.handle(i); } } //... std::vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 14. 14 То же самое, но лучше template<typename Handler> void for_each(const std::vector<int>& v, const Handler& h) { for (int i : v) { h.handle(i); } } //... std::vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 15. 15 То же самое, но лучше template<typename Handler> void for_each(const std::vector<int>& v, Handler& h) { for (int i : v) { h.handle(i); } } struct Sum { int sum = 0; void handle(int i) { sum += i; } }; std::vector<int> vect(1000000000); Sum handler; for_each(vect, handler);
  • 16. 16 То же самое, но лучше template<typename Handler> void for_each(const std::vector<int>& v, Handler& h) { for (int i : v) { h.handle(i); } } struct Sum { int sum = 0; void handle(int i) { sum += i; } }; std::vector<int> vect(1000000000); Sum handler; for_each(vect, handler); Бесплатное ускорение x9.2 (-5 тактов на вызов)
  • 17. 17 То же самое, но лучше template<typename Handler> void for_each(const std::vector<int>& v, Handler& h) { for (int i : v) { h.handle(i); } } struct PositivesSum { int sum = 0; void handle(int i) { if (i > 0) sum += i; } }; std::vector<int> vect(1000000000); PositivesSum handler; for_each(vect, handler); Бесплатное ускорение x2.8
  • 18. 18 Продолжаем улучшать template<typename Handler> void for_each(const std::vector<int>& v, const Handler& h) { for (int i : v) { h(i); } } //... std::vector<int> vect = {1,2,3}; MyHandler handler; for_each(vect, handler);
  • 19. 19 Совсем хорошо template<typename Handler> void for_each(const std::vector<int>& v, const Handler& h) { for (int i : v) { h(i); } } //... std::vector<int> vect = {1,2,3}; for_each(vect, [](int i){std::cout << i; });
  • 20. 20 Или так template<typename Handler> void for_each(const std::vector<int>& v) { for (int i : v) { Handler::handle(i); } } //... std::vector<int> vect = {1,2,3}; for_each<MyHandler>(vect);
  • 21. 21 Статический полиморфизм: плюсы  Нет накладных расходов на вызов методов  Не надо наследоваться  Не надо иметь дело с указателями  Контрвариантность параметров  Можно использовать лямбды
  • 22. 22 Статический полиморфизм: минусы  Нельзя положить в коллекцию  Сложно проверять правильность кода  Медленно компилируется  Может распухнуть бинарник  Нельзя явно задать интерфейсы  Мало помощи от IDE
  • 25. 25 Синтаксис иногда довольно странный… this->do(); typename T::iter f(typename T::iter i); this->template do<T>(); // WTF???
  • 28. 28 Template method struct Game { void play() { while(!end()) { makeTurn(); switchActivePlayer(); } } virtual bool end() = 0; virtual void makeTurn() = 0; virtual void switchActivePlayer() = 0; virtual ~Game() {} };
  • 29. 29 «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern
  • 30. 30 «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern template<typename Derived> class Game { void end() { static_cast<Derived*>(this)->end(); } };
  • 31. 31 «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern template<typename Derived> class Game { void end() { static_cast<Derived*>(this)->end(); } }; class Chess : public Game<Chess> { void end() {/*Check if king surrounded*/} };
  • 32. 32 «Виртуальный» вызов без virtual a.k.a. Curiously Recurring Template Pattern template<typename Derived> class Game { void end() { static_cast<Derived*>(this)->end(); } }; class Chess : public Game<Chess> { void end() {/*Check if king surrounded*/} }; std::unique_ptr<Game<Chess>> game(new Chess); game->play(); // calls Chess::end() inside
  • 33. 33 CRTP  «Виртуальный» метод может быть статическим  Может работать в ~7 раз быстрее виртуальной версии* ⃰ http://bit.ly/crtp_vs_virtual
  • 35. 35 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; }
  • 36. 36 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; }
  • 37. 37 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; }
  • 39. 39 Задача  Пишем инструмент для отладки  Есть множество объектов, не связанных какой-либо иерархией  Хотим сложить их в одну коллекцию, проитерироваться по ней, и распечатать содержимое объектов int x = 10; Foo bar; MagicCollection objects; objects.add(x); objects.add(bar); for (const auto& obj : objects) { obj.dump(); }
  • 40. 40 External polymorphism struct Dumpable { virtual void dump() const = 0; };
  • 41. 41 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 override { ::dump(value); } };
  • 42. 42 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 override { ::dump(value); } }; void dump(const Foo& foo) { foo.printToConsole(); }
  • 43. 43 External polymorphism class Dumper { using DumpablePtr = std::unique_ptr<Dumpable>; std::vector<DumpablePtr> dumpables; public: template<typename T> void add(const T& obj) { dumpables.push_back( DumpablePtr(new ConcreteDumpable<T>(obj))); } void dumpAll() const { for (const auto& d : dumpables) { d->dump(); } } };
  • 44. 44 External polymorphism class Dumper { using DumpablePtr = std::unique_ptr<Dumpable>; std::vector<DumpablePtr> dumpables; public: template<typename T> void add(const T& obj) { dumpables.push_back( DumpablePtr(new ConcreteDumpable<T>(obj))); } void dumpAll() const { for (const auto& d : dumpables) { d->dump(); } } } dumper; dumper.add(10); dumper.add(Foo()); dumper.dumpAll();
  • 45. 45 External polymorphism  Симбиоз виртуального и статического полиморфизма  Для поддержки нового типа T надо добавить только ::dump(T)  Можно строить параллельные иерархии
  • 47. 47 Новые возможности C++11: лямбды int x = 10; std::vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](int i){cout << i+x;});
  • 48. 48 Новые возможности C++11: лямбды int x = 10; std::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) const {std::cout << i+x;} }; for_each(v.begin(), v.end(), Lambda());
  • 49. 49 Новые возможности C++14: лямбды int x = 10; std::vector<int> v = { 1, 2, 3 }; for_each(v.begin(), v.end(), [x](auto i){cout << i+x;});
  • 50. 50 Новые возможности C++14: лямбды int x = 10; std::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) const {std::cout << i+x;} };
  • 51. 51 Новые возможности C++11: std::function void print(int i) { std::cout << i; } struct Print { void operator()(int i) { std::cout << i+x; } void print(int i) { std::cout << i+x; } } Print p; std::function<void(int)> p1 = print; std::function<void(int)> p2 = Print(); std::function<void(int)> p3 = std::bind(Print::print, p, _1); std::function<void(int)> p4 = std::bind(Print::print, &p, _1); std::function<void(const Print&, int)> p5 = &Print::print; std::function<void(int)> p6 = [](int i) { std::cout << i; };
  • 52. 52 Новые возможности C++11: лямбды и std::function auto lambda1 = []() {}; auto lambda2 = []() {}; lambda1(); // fast std::function<void()> f = []() {}; f(); // slow template<typename Handler> void for_each(const std::vector<int>& v, const Handler& h); void for_each(const std::vector<int>& v, std::function<void(int)> f);
  • 53. 53 Новые возможности C++11: std::function  Позволяют сохранить исполняемые объекты (включая лямбды), в том числе в коллекцию  Может быть медленной (~10 раз медленнее шаблонной функции)  Обеспечивает явную спецификацию интерфейса
  • 55. 55 Исходные условия id=1234 t time=2014.26.09 19:00 struct RecordBase { void Load(const std::string& str); std::string GetValue(const std::string& key) const; void SetValue(const std::string& key, const std::string& value); };  Хотим быстро создавать абстракции, позволяющие типизированно работать с записями
  • 56. 56 Версия 1.0 struct EventRecord : RecordBase { int GetId() const { const auto& str = GetValue("id"); // Parse id from str return id; } void SetId(int id) { // Serialize id to str SetValue("id", str); } time_t GetTs() const { const auto& str = GetValue("time"); // Parse ts from str return ts; } void SetTs(time_t ts) { // Serialize ts to str SetValue("date", str); } };
  • 57. 57 Версия 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)); } };
  • 58. 58 Уходим из :: struct Serializer { template<typename T> static T FromString(const std::string& str) { return ::FromString<T>(str); } template<typename T> static string ToString(const T& value) { return ::ToString(value); } };
  • 59. 59 Инкапсулируем логику RecordBase struct RecordBase { std::string GetValue(const std::string& key) const; void SetValue(const std::string& key, const std::string& value); template<typename T, typename Szr = Serializer> T Get(const string& key) const { return Szr::FromString<T>(GetValue(key)); } template<typename Szr = Serializer, typename T> void Set(const std::string& key, const T& value) { SetValue(key, Szr::ToString(ts)); } };
  • 60. 60 Упрощаем EventRecord struct EventRecord : RecordBase { int GetId() const { return Get<int>("id"); } void SetId(int id) { Set<>("id", id); } int GetTs() const { return Get<time_t, DateSerializer>("time"); } void SetTs(time_t ts) { Set<DateSerializer>("time", ts); } };
  • 61. 61 Еще больше инкапсуляции template<typename T, typename Szr = Serializer> class Property { RecordBase* record; std::string key; public: Property(RecordBase* record, const std::string& key) : record(record), key(key) {} T Get() const { return Szr::FromString(record->GetValue(key)); } void Set(const T& value) { record->SetValue(key, Szr::ToString(value)); } };
  • 62. 62 Итоговая версия struct EventRecord : RecordBase { Property<int> Id; Property<time_t, DateSerializer> Ts; EventRecord() : Id(this, "id"), Ts(this, "time") {} }; EventRecord record; record.Id.Set(123); time_t ts = record.Ts.Get();
  • 64. 64 Статический полиморфизм  Большая гибкость  Ограниченность в этапе компиляции  Поощряется свежими стандартами  Сложно писать библиотечный код  Просто писать клиентский код
  • 65. 65 Спасибо за внимание! Дмитрий Леванов Ведущий разработчик Крипта levanov@yandex-team.ru
  • 66. 66 Источники 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/