close

Вход

Забыли?

вход по аккаунту

код для вставкиСкачать
14.05.2014
Программирование
с использованием C++11
Полевой Дмитрий Валерьевич
к.т.н., доцент КиК
e-mail: [email protected]
1
14.05.2014
Неявные преобразования
• повышение
bool -> int
enum -> int или long
• обеспечение точности
int + long -> long
int + double -> double
• усечение
int n(f);
14.05.2014
2
2
14.05.2014
Явные преобразования
static_cast<Тип>(выражение)
• преобразование родственных типов
пример:
int roundVal = static_cast<int>(doubleVal);
14.05.2014
3
3
14.05.2014
Явные преобразования
const_cast<Тип>(выражение)
• изменение константности
пример:
char* pBeg = const_cast<char*>(p + n);
14.05.2014
4
4
14.05.2014
Явные преобразования
reinterpret_cast<Тип>(выражение)
• трактовка битового представления
• обычно применяется к указателям
пример:
// void *p
char* pBeg = reinterpret_cast<char*>(p);
14.05.2014
5
5
14.05.2014
Явные преобразования
dynamic_cast<Тип>(выражение)
• понижающее приведение
• 0 – если не из одной иерархии
пример:
// class Child : public Parent
Child* pCh = dynamic_cast<Child*>(pParent);
14.05.2014
6
6
14.05.2014
Преобразования в стиле С
• избегать использования
(Тип)выражение
или
Тип(выражение)
пример:
int roundVal = int(doubleVal + 0.5);
int roundVal = (int)doubleVal;
14.05.2014
7
7
14.05.2014
Выведение (auto)
• новый смысл ключевого слова в C++11
• тип переменной вычисляется
компилятором
пример:
auto iBeg{container.begin()};
auto iEnd{container.end()};
auto lPlu = [](int x)
{ return x + 3; }};
14.05.2014
8
8
14.05.2014
Выведение (decltype)
• статическое выведение типа по выражению
пример:
int x{5};
double y{5.1};
decltype(x) foo;
decltype(y) bar;
decltype(x + y) baz;
14.05.2014
// int
// double
// double
9
9
14.05.2014
Выведение типа
возвращаемого значения
template<typename T, typename U>
auto
anySum(const T& x, const U& y) ->
decltype(x + y)
{
return x + y;
}
14.05.2014
10
10
14.05.2014
Встраивание (inline)
• встраивание – генерация кода
– без вызова (передача параметров, возврат)
– нет накладных расходов на исполнение
– увеличивает объем исполняемого кода
– затрудняет отладку
• рекомендация компилятору
– может не выполняться
• определенные в классе (структуре) методы
являются встраиваемыми
14.05.2014
11
11
14.05.2014
Встраивание (пример)
inline int score(const int i)
{
…
return res;
}
14.05.2014
12
12
14.05.2014
Встраивание (пример)
class Vec
{
public:
int& operator[](const int i)
{
return data_[i];
}
private:
int data_[10];
};
14.05.2014
13
13
14.05.2014
Указатель на функцию
ТипВозврата (*имя)(список_аргументов)
пример:
bool (*pCmp)(const int, const int)(0);
pCmp = compareByIdx;
pCmp(i1, i2); // или (*pCmp)(i1, i2)
14.05.2014
14
14
14.05.2014
Функция обратного вызова
(call back function)
• передача исполняемого кода в качестве
одного из параметров другого кода
• позволяет
– исполнять в функции код, который задаётся в
аргументах при её вызове
– определять конкретный алгоритм на этапе
выполнения (а не компиляции) программы
14.05.2014
15
15
14.05.2014
Функция обратного вызова
(назначение)
• подзадача, которая используется для
обработки данных внутри некоторой
функции
• “телефонная связь”, используемая для того,
чтобы “связываться” с тем, кто вызвал
процедуру, при наступлении какого-то
события
14.05.2014
16
16
14.05.2014
Сортировка (qsort)
void qsort(void* base, size_t num,
size_t size,
int (*cmp)(const void*, const
void*));
• сортировка num блоков памяти размера
size в массиве base
• для сравнения используется функция cmp
14.05.2014
17
17
14.05.2014
Пример (qsort)
// pData – массив структур SBook
// num – число элементов в массиве
int (*pCmp)(const void*,
const void*)(cmpByYear);
qsort(pData, num, sizeof(*pData), pCmp);
14.05.2014
18
18
14.05.2014
Пример (qsort)
int cmpByYear(const void* pL, const void* pR)
{
assert((0 != pL) && (0 != pR));
SBook& lhs(*reinterpret_cast<SBook*>(pL));
SBook& rhs(*reinterpret_cast<SBook*>(pR));
return (rhs.m_year - lhs.m_year);
}
14.05.2014
19
19
14.05.2014
Проблемы call-back функций
• нет контроля типов
• накладные на вызовы функций
• глобальные данные
14.05.2014
20
20
14.05.2014
Стандартные алгоритмы
• шаблонные функции,
параметризуются через
– итераторы
– функторы
• если тип итераторов контейнера не
соответствует типу итераторов алгоритма,
поищите метод контейнера
14.05.2014
21
21
14.05.2014
std::find
(пример алгоритма)
template<class InputIt, class T>
InputIt find(InputIt first,
InputIt last, const T& value)
{
for(;first != last; ++first)
if (*first == value)
break;
return first;
}
14.05.2014
22
22
14.05.2014
std::sort
(варианты функции)
• для контейнеров с произвольным доступом
template<class RandAccIt>
void sort(RandAccIt first,
RandAccIt last)
template<class RandAccIt,
class Compare>
void sort(RandAccIt first,
RandAccIt last, Compare comp)
14.05.2014
23
23
14.05.2014
std::sort
(варианты функции)
• для списка
void list::sort()
template <class Compare>
void list::sort(Compare comp)
14.05.2014
24
24
14.05.2014
Функтор
(функциональный объект)
• экземпляр любого класса, перегружающего
operator()
• используется для параметризации
алгоритмов
• может встраиваться компилятором в тело
алгоритма (в отличии от обычной функции)
14.05.2014
25
25
14.05.2014
Функтор
(функциональный объект)
• может содержать данные
• может копироваться в процессе работы
алгоритма
– для некоторых алгоритмов не должен иметь
изменяемого состояния
14.05.2014
26
26
14.05.2014
Преимущества функторов перед
функциями
• может иметь состояние
• может обеспечить операции
предварительной инициализации данных
• тип может использоваться как параметр
шаблона для указания определённого
поведения
• может выполнятся быстрее
(inline может быть встроен эффективнее,
чем вызов функции через указатель)
14.05.2014
27
27
14.05.2014
Свойства функторов
(traits)
• информация о типах аргументов и
результата
• используются в шаблонном коде
14.05.2014
28
28
14.05.2014
Предикат
• возвращает логическое значение bool
• м.б. унарным или бинарным в STL
• может копироваться алгоритмами STL
– количество копирований при использовании в
алгоритмах не определено
• не должен менять своё состояние при
копировании или вызове
14.05.2014
29
29
14.05.2014
Лямбда
• Замыкание – функция
– в теле которой присутствуют ссылки на
переменные, объявленные вне тела этой функции
и не в качестве её параметров (а в окружающем
коде)
– которая ссылается на свободные переменные в
своём контексте
• Лямбда-функция создает замыкание
– безымянный объект-функцию, способный
захватывать переменные в контекст
14.05.2014
30
30
14.05.2014
Захват значений (capture)
• какие символы, видимые в области, где функция
объявлена, будут видны внутри тела функции и как
• [a, &b]
– a захвачена по значению, b захвачена по ссылке ()
• [this]
– указатель this по значению
• [&]
– захват всех символов по ссылке
• [=]
– захват всех символов по значению
• []
– ничего не захватывает
14.05.2014
31
31
14.05.2014
Лямбда (синтаксис)
[capture] { body }
• функция не принимает аргументов, как
если бы список параметров был ()
пример:
[]{ return 0; }
14.05.2014
32
32
14.05.2014
Лямбда (синтаксис)
[capture](params) { body }
• возможна передача параметров по списку
• возвращаемый тип выводится
– если body состоит из одной инcтрукции return, то
возвращаемый тип является типом возвращаемого
выражения (после неявных преобразований)
– в противном случае возвращаемый тип void
пример:
[](int i){ return i + 1; }
14.05.2014
33
33
14.05.2014
Лямбда (синтаксис)
[capture](params)->ret { body }
• возвращаемый тип указывается явно
• константная лямбда
– объекты, захваченные копированием,
не могут быть изменены
пример:
[](int i)->double {
return i + 1.0;
}
14.05.2014
34
34
14.05.2014
Лямбда (синтаксис)
[capture](params) mutable
exception attribute -> ret
{ body }
• возможность изменять параметры
– захваченные копированием
– вызывать их неконстантные функции-члены
• спецификация исключения (в т.ч. noexcept)
• спецификация атрибута для оператора () типа
замыкания
14.05.2014
35
35
14.05.2014
Обертка функции (function)
• заголовочный файл <functional>
• хранение, копирование и вызов
произвольных вызываемых объектов
– функция (в т.ч. метод)
– лямбда-выражение
– выражение связывания
– другие функциональные объекты
14.05.2014
36
36
14.05.2014
Обертка функции (пример)
void printLetter(const char c)
{
cout << c << endl;
}
…
function<void(const char)>
fPrint{printLetter};
fPrint ('Q');
14.05.2014
37
37
14.05.2014
Обертка лямбды (пример)
function<void()> fPrint{
[] ()
{
cout << "Hello world!" << endl;
};
fPrint();
14.05.2014
38
38
14.05.2014
Обертка связывателя (пример)
void printLetter(const char c)
{
cout << c << endl;
}
…
function<void()>
fPrint{bind(printLetter, ‘~')};
fPrint();
14.05.2014
39
39
14.05.2014
Обертка метода (пример)
struct A {
A(const int num) : num_(num){}
void printNumberLetter(const char c) const
{ cout << "N: " << num_ << " L: " << c; }
const int num_;
};
…
function<void(const A&, const char)>
fPrint{&A::printNumberLetter};
A a(10);
fPrint(a, 'A');
14.05.2014
40
40
14.05.2014
«Проблемы» вызова
• происходит вызов
function::operator()
• целевой объект отсутствует
• запускается исключение
bad_functional_call
14.05.2014
41
41
14.05.2014
«Проблемы» вызова (пример)
// http://ru.wikipedia.org/wiki/Functional_(C++)
#include <iostream>
#include <functional>
int main()
{
std::function<void()> func = nullptr;
try {
func();
} catch(const std::bad_function_call& e) {
std::cout << e.what() << std::endl;
}
}
14.05.2014
42
42
14.05.2014
Связыватель (bind)
• частичное применение функций
• создает новый функциональный объект,
привязывая некоторые аргументы к нему
– непосредственно значения аргументов
– специальные имена, определенные в
пространстве имен placeholders
(определяют порядок аргументов у
возвращаемого функционального объекта)
14.05.2014
43
43
14.05.2014
Связыватель (пример)
//http://ru.wikipedia.org/wiki/Functional_(C++)
#include <iostream>
#include <functional>
using namespace std;
int myPlus(int a, int b) {return a + b;}
int main()
{
function<int (int)> f(bind(myPlus,
placeholders::_1, 5));
cout << f(10) << endl;
}
14.05.2014
44
44
14.05.2014
Производящая функция
• создание объекта заданного типа
• в шаблонном варианте автоматически
выводит тип объекта по типам аргументов
14.05.2014
45
45
14.05.2014
Устаревшее в С++11
•
•
•
•
•
•
•
•
unary_function
binary_function
bind1st
bind2nd
ptr_fun
pointer_to_unary_function
pointer_to_binary_function
…
14.05.2014
46
46
14.05.2014
std::find_if
(пример алгоритма)
template<class InputIt,
class Predicate>
InputIt find_if(InputIt first,
InputIt last, Predicate pred)
{
for(; first != last; ++first)
if (pred(*first))
break;
return first;
}
14.05.2014
47
47
14.05.2014
Стандартные алгоритмы
• информация о последовательности
• поиск
• модификация, в т.ч.
– слияние
– удаление
– сортировка
• перестановка
14.05.2014
48
48
14.05.2014
Стандартные алгоритмы
(для сортированных диапазонов)
• поиск (бинарный)
• слияние
• теоретико-множественные
– проверка вхождения
– объединение
– пересечений
– разница
– симметрическая разница
14.05.2014
49
49
14.05.2014
Поиск
It find(It first,It last,
const T& val);
It find_if(It first,It last,
UnF pred);
14.05.2014
50
50
14.05.2014
Поиск (бинарный)
bool binary_search(
It first,It last, const T& val
[, Compare comp]);
It lower_bound(
It first,It last, const T& val
[, Compare comp]);
It upper_bound(
It first,It last, const T& val
[, Compare comp]);
14.05.2014
51
51
14.05.2014
Информация о диапазонах
• count
– подсчет элементов
• count_if
– подсчет элементов с предикатом
• equal
– сравнение диапазонов
• lexicographical_compare
– лексикографическое сравнение диапазонов
14.05.2014
52
52
14.05.2014
Модификация диапазонов
•
•
•
•
•
•
•
•
for_each
transform
fill
generate
swap
equal
rotate
random_shaffle
14.05.2014
• remove (_if)
• copy (_if)
• replace
• insert
• partition
• unique
53
53
14.05.2014
std::for_each
(вызов функции для элементов)
template<class InpIt, class Func>
Function for_each(InpIt first,
InpIt last, Func f)
{
for ( ; first!=last; ++first)
f(*first);
return f;
}
14.05.2014
54
54
14.05.2014
std::copy
(копирование диапазона)
template<class InpIt, class OutIt>
OutIt copy(InpIt first, InpItlast,
OutIt result )
{
while (first != last)
*result++ = *first++;
return result;
}
14.05.2014
55
55
14.05.2014
Копирование диапазона в поток
• копирование диапазона может
использоваться для ввода/вывода
пример:
ostream_iterator<int> out_it (cout,
", ");
copy(vec.begin(), vec.end(), out_it);
14.05.2014
56
56
14.05.2014
Адаптирующие итераторы
insert_iterator
back_insert_iterator
front_insert_iterator
14.05.2014
57
57
14.05.2014
std::back_insert
(адаптирующий итератора)
• вставка элементов в конец контейнера для
алгоритмов переписывающих значения
(например, copy)
• контейнер должен обеспечивать
push_back
• вызов operator= приводит к вставке,
остальные операции ничего не меняют
14.05.2014
58
58
14.05.2014
std::back_inserter
(производящая функция)
template <class Cont>
back_insert_iterator<Cont>
back_inserter(Cont& x)
14.05.2014
59
59
14.05.2014
Конструирование алгоритмов
• как «склеить» две последовательности?
– скопировать одну в конец второй
пример:
list<int>::iterator it(firList.begin());
advance (it, 3);
insert_iterator<list<int> >
insertIt(firList, it);
copy(secList.begin(),secList.end(),
insertIt);
14.05.2014
60
60
14.05.2014
Операции над итераторами
• advance
– смещение итератора
• difference
– расстояние между итераторами
14.05.2014
61
61
14.05.2014
Рекомендации
• избегайте повторного написания
алгоритмов
• конструируйте алгоритмы
• помните о копировании объектов
• читайте книги и практикуйте 8)
14.05.2014
62
62
14.05.2014
А где в stl стек или очередь?
• адаптер
– класс преобразующий интерфейс объекта к
нужному интерфейсу
– в stl – шаблонный класс
• адаптеры контейнеров
stack
queue
prioriy_queue
14.05.2014
63
63
14.05.2014
std::stack (адаптер)
template<class T,
class Cont = deque<T> >
class stack;
bool empty() const
size_t size() const
value_type& top() // const
void push(const T&)
void pop()
14.05.2014
64
64
14.05.2014
std::queue (адаптер)
template<class T,
class Cont = deque<T> >
class queue;
bool empty() const
size_t size() const
value_type& front()
value_type& back() const
void push(const T&)
void pop()
14.05.2014
65
65
14.05.2014
std::priority_queue (адаптер)
template<class T,
class Cont = vector<T>,
class Cmp = less<typename Cont::value_type>
>
class priority_queue;
bool empty() const
size_t size() const
value_type& top() // const
void push(const T&)
void pop()
14.05.2014
66
66
1/--страниц
Пожаловаться на содержимое документа