1 / 39

Про зачет

Про зачет. Про зачет и т.д. - 1. 11 задач На сайте скоро будут возможные темы задач Что-то про наследование Что-то про string ( собственный) или list Про map Про value_type или decltype Про лямбда … и еще …. Баллы  … 20  9 задач 30  8 задач 40  7 задач

Download Presentation

Про зачет

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Про зачет

  2. Про зачет и т.д. - 1 • 11 задач • На сайте скоро будут возможные темы задач • Что-то про наследование • Что-то про string (собственный) или list • Про map • Про value_type или decltype • Про лямбда • … и еще … • Баллы  … • 20  9 задач • 30  8 задач • 40  7 задач • 50  6 задач • 60  5 задач • 2 мая занятий не будет, но, скорее всего, будут доп.слайды и доп.задачи – только для тех, кто хочет набрать много баллов

  3. Про зачет и т.д. - 2 • Можно пользоваться любыми материалами • Нельзя пользоваться чьей то помощью, в любом виде. Это по возможности будет проверятся. И если будет обнаружено, что кто-то пользуется помощью, зачет для этого человека будет окончен и все задачи не засчитаны (( • Сдавать можно как угодно (на листочках, на каком-нибудь носителе) • Можно сдавать по частям, например 4 задачи в один день и 5 – в другой (каждая задача засчитывается отдельно) • Первая попытка (предварительная): • 16 мая на 2 часе • потом 23 мая • (м.б. еще одна до 23? – посмотрим по результатам 16 мая)

  4. Д.з.

  5. Среднее арифметическое положительных чисел – с помощью decltype template <class T> auto averagepos(T b, T e) -> decltype(*b/2.0) { decltype(*b/2.0) sum = 0; int n = 0; for (T p = b; p != e; p++) { if(*p > 0) { sum+=*p; n++; } } return sum / n; } vector<double> v; cout << averagepos (v.begin(), v.end());

  6. month.h const char* monthName(int month); month.cpp #include "month.h" #include <cassert> namespace { const char* monthNames[12] = { "January“, "February", … "December", } }; const char* monthName(int month) { assert(month >= 1 && month <=12); return monthNames[month-1]; } main.cpp #include "month.h" int main() { cout << monthName(4); Типичная ошибка:using namespace std; в h файлеЛучше не писать! Задача 1: Название месяца

  7. Задача 3: В каждом векторе хотя бы одно положительное число vector<vector<int>> vv; … bool b = all_of(vv.begin(), vv.end(), [] (const vector<int>& v) { return any_of(v.begin(), v.end(), [] (int i) { return i > 0; }); } ); • Я бы, наверное, выписывал условия отдельно auto pos = [] (int i){ return i > 0; }; auto anyPos = [&] (const vector<int>& v) { return any_of(v.begin(), v.end(), pos); }; bool b = all_of(vv.begin(), vv.end(), anyPos);

  8. Вариант с union union { double x; int a[2]; }; x = 2.71828; cout << a[0] << " " << a[1]; Вариант с преобразованием указателя x = 2.71828; int* p = (int*)&x; cout << p[0] << " " << p[1]; Или лучше так: int* p = reinterpret_cast<int*>(&x); Задача 4: из каких int состоит double?

  9. Про наследование

  10. Эту задачу вы можете решить до следующего занятия, до 16.5 Пока только пример использования // полиморфный массив vector<person*> v; v.push_back(new student(“Петров“,341)); v.push_back(new professor(“Сидоров“,“алгебра“)); v.push_back(new student(“Чижиков“,342)); … // Печатаем double sum = 0; for (auto p=v.begin(); p!=v.end(); p++) { cout << *p->getName(); } Массив, который может содержать значения разных типов. Благодаря виртуальным функциям мы объекты разных типов можем обрабатывать единообразно Задача 5: Студенты и преподаватели ! ! ! !

  11. // Иерархия классов class person { public: virtual … getName …// Еще методы… }; class student: public person {// Методы… }; class professor : public person { // Методы… }; // Считаем количество студентов int cnt = 0; for (auto p = v.begin(); p != v.end(); p++) { if (typeid(**p) == typeid(student)) cnt++; } Задача 6:Сколько студентов?

  12. Хочется использовать typeid? Скорее всего, надо ввести виртуальную функцию. (smell…) auto id = typeid(*p); if (id == typeid(circle)) cout << "Это круг"; else if (id == typeid(square)) cout << "Это квадрат"; else if (id == typeid(triang)) cout << "Это треугольник"; Придеться менять для каждой новой фигуры…  Лучше добавить виртуальную функциюgetName() cout<< "Это" << p->getName(); То есть: Желательно, что бы код, который работает с shape вообще не знал о том, какие есть производные типы, и сколько их Иначе при добавлении нового производного типа все может сломаться Почему плохо использовать RTTI? Это, кстати, называется принцип подстановочности Лисков

  13. Когда все-таки имеет смысл использовать RTTI? Если мы не можем добавить виртуальную функцию в базовый класс.(Это класс из библиотеки, например.)(Например, в MFC классы, производные от CView) Когда это все-таки имеет смысл?

  14. Преобразование из числа в строку (пригодится для тех, кто соберется еще сделать задачу про студентов и преподавателей)

  15. Способ С++ строковые потоки #include <sstream> ostringstreamstr_out; strout << i << " " << x; string s = str_out.str(); И аналогично istringstream.string s; …istringstreamstr_in(s); str_in >> i >> x; C++11 – to_string #include <string> … string s = to_string(i); Более старые способы: atoi, itoa, atof, _fcvt и т.д. Форматный ввод/вывод в т.ч. в строку. char s[20]; sprinf(s, "%10.3lf", x); Преобразования строка  число

  16. Прием trait («класс свойств») 16

  17. template <class T> class numeric_limits { public: static T max(); // Достаточно объявления. // Описание можно не задавать, // все равно оно не потребуется }; // Специализации template<> // Для int inline int numeric_limits<int>::max() { return 0x7FFFFFFF; } template<> // Для unsigned inline unsigned numeric_limits<unsigned>::max() { return 0xFFFFFFFF; } template<> // Для short inline short numeric_limits<short>::max() { return 0x7FFF; } // Пример вызова cout << numeric_limits<int>::max(); cout << numeric_limits<unsigned>::max(); cout << numeric_limits<short>::max(); Задача 2: numeric_limits

  18. Trait – класс свойств Фактически задается функция int 0x7FFFFFFF unsigned 0xFFFFFFFF … и т.д. … Умное слово.. • Trait (класс свойств) • Шаблон, который для типа определяет его свойства • Обычно содержит только typedef и статические функции. Основной прием при программировании шаблонов... (Если у вас непонятная проблема с шаблонами – попробуйте traits…) Замечание: Если бы int, unsigned и т.д. были бы типами, и мы могли быопределять для них методы – все было бы проще…

  19. Шаблоны и функции с переменным числом аргументов 19

  20. Шаблоны с переменным количеством параметров (variadic templates) • С++11 (Visual Studio 2013) • Цель print(1, 2, 3); print(1,2,3,4,5,6); print(3.14, 2.7); print(1, "abc", 3.14); • Решение template <class T1, class ... T> void print(const T1& first, const T& ... other) {cout << first << "\n"; print(other...); } void print() { } • class … T – может быть сколько угодно параметров (может быть, 0)(parameter pack) • T … params – то же в заголовке функции • params… - список параметров передаем в какую-то другую функцию Вызываем рекурсивно, но параметров уже меньше А это чтобы рекурсия завершилась

  21. Еще один способ - initializer_list #include <initializer_list> cout << print({1,2,3,4}); template <class T> void print(const T& lst) { for(auto p = lst.begin(); p!= lst.end(); p++)& cout << *p << “\n”; } • А также можно использовать va_arg и т.д., но это морально устревший способ

  22. Умные указатели 22

  23. shared_ptr • Указатели со счетчиком ссылок #include <memory> { shared_ptr<int> p(new int(56)); … { shared_ptr<int> p1 = p; … // Два указателя на 56 }// Теперь только один … } // Теперь нет указателей. Память освобождается • Для управления разделяемыми объектами

  24. Как shared_ptr, но без разделения ссылок) Например: когда лень писать в деструкторе delete class abc { klm* p; public: abc() : p(new klm(56)) {} ~abc() { delete p; } }; А присваивание и к-р копирования? Можно так: class abc { unique_ptr<int> p; public: abc() : p(new int(56)) {} // При уничтожении p //delete автоматически. // Т.е. достаточно деструктора // по умолчанию }; присваивание и копирование автоматически запретятся Еще есть weak_ptr unique_ptr

  25. Препроцессор 25

  26. На самом деле в C++ два языка • До компилятора работает препроцессор • Текст  промежуточный файл (тоже текст на C++) • Результат работы препроцессора потом обрабатывается компилятором • Есть опция Generate preprocessed file – можно посмотреть промежутoчный файл. Язык препроцессора: • Очень простой • Почти ничего не знает о синтаксисе C++ • Конечно, совсем ничего не знает о значения переменных и т.д. • Считается, что лучше использовать поменьше (Я в общем, согласен, но иногда удобно…)

  27. Директивы препроцессора • На отдельной строке • Начинаются с # Например: #define ABC 123 #include <map> • Если не помещается на одну строку: символ \ на конце строки. Например: #define ABC \ 123 Замечание: После \ не должно быть даже пробелов!

  28. #define ABC 123 Заменить всюду в тексте ABC на 123 Принято использовать заглавные буквы Может быть с параметрами #define SQR(x) x * x Заменить всюду в тексте SQR(что-то) на что-то * что-то Например:SQR(a[i])  a[i] * a[i] Может быть без правой части #define ABC(x) Всюду заменить ABC(что-то) на пустую строку (т.е. выкинуть). #define

  29. Вместо const #define SIZE 100  const int size = 100; (или enum) Вместо inline или template #define SQR(x) x*x  template <class T>inline T sqr(T x) { return x*x; } Где не надо использовать #define

  30. Когда имеет смысл использовать #define? • Если хотим быстро и эффективно добавлять / убирать какой-то код (для отладки) #define TRACE(x) cout << (x) TRACE(a[i]);  cout << (a[i]); Когда отладим, просто напишем: #define TRACE(x) и все отладочные печати вообще исчезнут из кода • Если то, что мы хотим записать в define – не функции. (пример на следующем слайде)

  31. template<> inline int numeric_limits<int>::max() { return 0x7FFFFFFF; } template<> inline unsigned numeric_limits <unsigned>::max() { return 0xFFFFFFFF; } … // Вариант с препроцессором #define NUMLIM(type, val) \ … какое-то определение … NUMLIM(int, 0x7FFFFFFF); NUMLIM(unsigned, 0xFFFFFFFF); … Когда имеет смысл использовать #define? Пример

  32. Опасности (почему #define хуже inline функции) #define SQR(x) x*x • Проблема: приоритет операций SQR(x+1)  x+1 * x +1 Решение: • Взять все в скобки • И аргументы взять в скобки #define SQR(x) ((x)*(x)) • Еще проблема (неразрешимая..): SQR(i++)

  33. Оператор # • # x - stringize Взять x в кавычки. #define ABC(x) #x ABC(klmn)  “klmn" Удобно в отладочных макро: #define TRACE(x) cout << #x " = " << (x) TRACE( 2*a[i+j] )  cout << "2*a[i+j]" " = " << (2*a[i+j])

  34. ## - склейкаa ## x – записать a и значение x подряд, без пробела. #define ABC(x) a ## x ## b ABC(klmn)  aklmnb Пример (не убедительный…): #define MYDEFS(x) \ int i##x; \ string s##x; \ double dbl##x; MYDEFS(Student)  int iStudent; string sStudent; double dblStudent; Оператор ##

  35. Д.з 35

  36. Д.з. 1 • Пусть я хочу для данного типа проверять, это указатель на что-то (что угодно) или не указатель. Т.е. я хочу описать что-то, похожее на логическую функцию, которая, например, для int* возвращала бы true, адля double – false. Попробуйте, пожалуйста, описать что-то такое и приведите примеры использования. • Замечание: Это похоже на функцию, но не может быть просто функцией – ее параметр не значение, а тип. • Подсказка: trait • Замечание: на самом деле, есть такой стандартный шаблон, можно просто его найти в документации и показать, как он используется, это будет засчитано. 1а. Задачу 1 относительно легко решить, если под указателями подразумевается все, что описано, как что-то*. А если подразумевать под указателями все, для чего определена операция *? Например shared_ptr. Я думаю, что это тоже возможно, если использовать довольно хитрый прием, который называется SFINAE. Но, честно скажу, так сразу не могу написать. Если кто-то сделает задачу в таком варианте, получит еще 2 балла. Но в этой задаче нельзя использовать стандартные шаблоны 36

  37. Д.з. 2 • Описать шаблон функции, которая ищет максимум для любого количества параметров и для любых числовых типов. Примеры вызова: cout << maximum(1, 2, 3); cout << maximum(5.6, 7.1, 10.0, 2.2, 123); Если вы напишете вариант с использованием initalizer_list(там интерфейс будет, понятно, немного другой), то за это будет еще 0.5 балла. 37

  38. Д.з. - 3 • Снова задача про RAII. Была примерно такая задача, на 4 занятии void f(stack& s){klm* p = new klm(100); // Динамически отводим какой-то обьект // … тут, допустим, мы что-то делаем с p и scout << s.pop(); // … а тут еще что-то делаем с p и s delete [] p; // Потенциальная утечка памяти: delete может и не вызваться! } Покажите, как справиться с возможной проблемой утечки памяти с помощью unique_ptr. (Это, на самом деле, очень простая задача, буквально одна строчка) 38

  39. Д.з. - 4 • Реализовать NUMLIM (см. пример выше в слайдах) • Пример на использование shared_ptr Я хочу вести адресную книгу. Как выяснилось, у меня много знакомых, которые живут в одном и том же месте. Поэтому я решил, что будет удобно, если при добавлении нового человека, можно будет адресне указывать, а указать, что он живет там же, где другой, адрес которого я уже задал. В результате я хочу сделать вот что: • Описать структуру или класс address c полями "город","улица", "дом" • В классе addressbook я хочу, чтобы были методы - add(имя, город, улица, дом) - addNeighbour(имя нового человека, имя)- remove(имя) – удалить человека из книги - printaddres(имя) – напечатать адрес человка (В последних 2 методах будем считать что 'имя' точно у нас уже записано, это можно не проверять). В качестве представления я бы хотел использовать map, где ключ – это имя, а значение – shared_ptr на адрес (shared_ptr, чтобы не хранить адрес несколько раз). Попробуйте написать такой класс. 39

More Related