Vladislav Shpilevoy PRO
Database C developer at Tarantool. Backend C++ developer at VirtualMinds.
Дмитрий Калугин-Балашов
Руководитель группы разработки
d.kalugin-balashov@corp.mail.ru
Владислав Шпилевой
Программист
v.shpilevoy@corp.mail.ru
Максим Тремпольцев
Программист
m.trempoltsev@corp.mail.ru
Лекция 1:
Контейнеры STL
Умные указатели
Аллокаторы
С++98
С++03 - патч для 98
С++11 - повышение абстракции
С++14 - auto auto auto
С++17 в разработке
С++98
С++03 - патч для 98
С++11 - повышение абстракции
С++14 - auto auto auto
С++17 в разработке
Это множества значений, или пар значений.
- std::vector
- std::deque
- std::forward_list
- std::list
- std::array
- std::set
- std::map
- std::multiset
- std::multimap
a1
a2
a4
a3
a5
a6
a8
a7
a9
a10
a < a
i
i + 1
Несбалансированность
RB-дерево - двоичное дерево поиска с самобалансировкой
Правила:
"Черная" высота = 2
Новый узел красный, но предок должен быть черным. Перекрасим вершины
A
B
C
D
A
B
C
D
Новое дерево удовлетворяет определению RB-дерева
...
...
...
...
...
...
A
B
C
D
Что, если перекрашивание не помогает?
Просто сделать B черным нельзя - может нарушиться "черная" высота дерева! Нужно выполнить поворот перекраску дерева.
x
z
y
B
D
A
C
x
z
y
Новое дерево удовлетворяет определению RB-дерева
Del
null
null
Удалить и ребалансировать
Del
null
Заменить единственным потомком, ребалансировать
Chld
null
leaf
null
Del
leaf
Chld
subtree
Заменить наименьшим элементом из правого поддерева, ребалансировать
Chld
subtree
Удаление как в бинарном дереве + балансировка
Chld
http://goo.gl/vBHT7B
Ассоциативные контейнеры google
btree_set
btree_map
btree_multiset
btree_multimap
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
k1
Контейнеры-адаптеры
- std::queue
- std::stack
- std::priority_queue
Адаптер - обертка над другим контейнером, предоставляет стандартный интерфейс
Бэкэнд: std::list
или std::deque
Бэкэнд: std::list
, std::deque
или std::vector
Бэкэнд: std::vector
или std::deque
Псевдоконтейнеры
- std::bitset
- std::basic_string
- std::valarray
Оптимизировано хранение, фиксирован размер, специальные ссылки
Для хранения строко-подобных объектов. Оптимизировано хранение, требует интерфейс.
Оптимальное хранение чисел и выполнение мат. операций. Расширенный интерфейс.
Хэш-таблицы
Хэш-функция - сюрьективное отображение
vlad
dima
leha
serg
max
ivan
1
4
2
3
Хэш-таблицы: коллизии
leha
serg
1
Коллизия. Решение - хранить список.
leha
serg
1
leha
serg
Второе решение - применять другие хэш функции к новому элементу, пока не получим не занятое значение хэша.
Хэш-таблицы STL
- std::unordered_set
- std::unordered_multiset
- std::unordered_map
- std::unordered_multimap
Boost circular buffer
boost::circular_buffer
boost::circular_buffer_space_optimized
Источник: http://goo.gl/myJ46d
Источник: http://goo.gl/PVu96v
Умные указатели
#include <iostream>
class SmartIntPtr {
int *ptr;
public:
SmartIntPtr(int *src = nullptr) : ptr(src) { }
~SmartIntPtr() {
if (ptr != nullptr)
delete ptr;
std::cout << "deletion of data" << std::endl;
}
int &operator*() { return *ptr; }
};
int main()
{
int *data = new int;
*data = 10;
SmartIntPtr smp(data);
std::cout << "data: " << *smp
<< std::endl;
return 0;
}
data: 10
deletion of data
Умные указатели: шаблоны
Можно унифицировать шаблонами
#include <iostream>
template<class T>
class SmartPtr {
T *ptr;
public:
SmartPtr(T *src = nullptr) : ptr(src) { }
~SmartPtr() {
if (ptr != nullptr)
delete ptr;
std::cout << "deletion of data" << std::endl;
}
T &operator*() { return *ptr; }
T *operator->() { return ptr; }
};
struct MyStruct {
int foo_bar;
void call_me_please() {
std::cout << "thanks"
<< std::endl;
}
};
int main()
{
SmartPtr<MyStruct> smp(new MyStruct);
smp->call_me_please();
return 0;
}
thanks
deletion of data
Умные указатели: существующие реализации
Некорректное копирование указателя.
#include <memory>
int main()
{
std::auto_ptr<int> p1(new int);
std::auto_ptr<int> p2;
p2 = p1;
*p1 = 100; //Segmentation Fault
return 0;
}
Умные указатели: существующие реализации
Уникальное владение объектом
#include <memory>
int main()
{
std::unique_ptr<int> p1(new int);
std::unique_ptr<int> p2;
p2 = p1; //Compilation Error
return 0;
}
Перемещение специфицируется явно
#include <memory>
int main()
{
std::unique_ptr<int> p1(new int);
std::unique_ptr<int> p2;
p2 = std::move(p1); //Ok
return 0;
}
Умные указатели: существующие реализации
Множественное владение объектом
#include <memory>
int main()
{
std::shared_ptr<int> p1(new int);
std::shared_ptr<int> p2;
*p1 = 0;
p2 = p1; //Ok
*p2 = 20;
std::cout << *p1 << std::endl;
// Prints 20
return 0;
}
Отслеживает количество ссылок
Объект
cnt=3
ptr1
ptr2
ptr3
Умные указатели: существующие реализации
#include <memory>
#include <iostream>
struct A;
struct B {
std::shared_ptr<A> p;
~B() { std::cout << "destr B" << std::endl; }
};
struct A {
std::shared_ptr<B> p;
~A() { std::cout << "destr A" << std::endl; }
};
int main() {
A *a = new A;
B *b = new B;
a->p.reset(b);
b->p.reset(a);
delete a;
return 0;
}
$ ./a.out
destr A
destr B
destr A
malloc: *** error pointer being
freed was not allocated
*** set a breakpoint in
malloc_error_break to debug
Abort trap: 6
Умные указатели: существующие реализации
#include <memory>
#include <iostream>
struct A;
struct B {
std::shared_ptr<A> p;
~B() { std::cout << "destr B" << std::endl; }
};
struct A {
std::weak_ptr<B> p;
~A() { std::cout << "destr A" << std::endl; }
};
int main() {
A *a = new A;
B *b = new B;
a->p = std::shared_ptr<B>(b);
b->p.reset(a);
delete a;
return 0;
}
$ ./a.out
destr B
destr A
By Vladislav Shpilevoy
Database C developer at Tarantool. Backend C++ developer at VirtualMinds.