Advertisement
Guest User

Untitled

a guest
Jan 27th, 2020
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.07 KB | None | 0 0
  1. Question 3
  2. Const correctness
  3. Это означает использование ключевого слова const для предотвращения мутации объектов const.
  4.  
  5. В случаях pass by reference-to-const и pass by pointer-to-const любые попытки изменить строку std::вызывающего объекта в функциях f() будут помечены компилятором как ошибка во время компиляции. Эта проверка выполняется во время компиляции: нет пространства или времени выполнения скорость затрат по строительству. В случае pass by value (f3 ()) вызываемая функция получает копию строки std:: вызывающего объекта. Это означает, что f3() может изменить свою локальную копию, но копия будет уничтожена, когда f3 () вернется. В частности, f3 () не может изменить объект std::string вызывающего объекта.
  6.  
  7. В качестве противоположного примера предположим, что вы хотите создать функцию g (), которая принимает std::string, но вы хотите, чтобы вызывающие знали, что g () может изменить объект std::string вызывающего объекта. В этом случае g () может получить свой параметр std:: string…
  8. Объявление постоянства параметра - это просто еще одна форма безопасности типов.
  9.  
  10. Если вы обнаружите, что безопасность обычного типа помогает вам корректировать системы (это действительно так; особенно в больших системах), вы также найдете, что помогает корректность const.
  11.  
  12. Преимущество корректности const состоит в том, что она предотвращает непреднамеренное изменение того, что вы не ожидали, что будет изменено. В конечном итоге вам нужно украсить свой код несколькими дополнительными нажатиями клавиш (ключевое слово const), с тем преимуществом, что вы сообщаете компилятору и другим программистам некоторую дополнительную важную семантическую информацию — информацию, которую компилятор использует для предотвращения ошибок, а другие программисты используют в качестве документации.
  13.  
  14. Это означает, что p указывает на объект класса X, но p не может быть использован для изменения этого объекта X (Естественно, p также может быть NULL).
  15.  
  16. Прочитайте его справа налево: "p-это указатель на X, который является постоянным.”
  17.  
  18. В чем разница между “const X* p”, “X* const p” и “const X* const p”?
  19. Прочитайте объявления указателя справа налево.
  20.  
  21. const X* p означает "p указывает на X, который является const": объект X не может быть изменен через p.
  22. X * const p означает " p-это указатель const на X, который не является const”: вы не можете изменить сам указатель p, но вы можете изменить объект X через p.
  23. константный х* const и Р означает “P-это константный указатель на X, который является константой”: вы не можете изменить указатель п себя, и вы не можете изменить объект X через Р.
  24.  
  25. Что означает "const X& x"?
  26. Это означает, что x псевдонимы объекта X, но вы не можете изменить этот объект X через x.
  27.  
  28. Прочитайте его справа налево “ " x-это ссылка на X, который является const.”
  29.  
  30. Например, если класс X имеет функцию-член const, такую как inspect () const, можно сказать x. inspect (). Но если класс X имеет неконстантную функцию-член под названием mutate (), то будет ошибкой, если вы скажете x.mutate ().
  31.  
  32. class Fred {
  33. public:
  34. void inspect() const; // This member promises NOT to change *this
  35. void mutate(); // This member function might change *this
  36. };
  37.  
  38. void userCode(Fred& changeable, const Fred& unchangeable)
  39. {
  40. changeable.inspect(); // Okay: doesn't change a changeable object
  41. changeable.mutate(); // Okay: changes a changeable object
  42. unchangeable.inspect(); // Okay: doesn't change an unchangeable object
  43. unchangeable.mutate(); // ERROR: attempt to change unchangeable object
  44. }
  45.  
  46. Константная ссылка
  47. Обычная ссылка - равна чему-то
  48. int a;
  49. int& ar = a;
  50. ar = 5;//поменяется зачение а
  51. а = 9;
  52. ar = b;//ничего не сделается
  53.  
  54. int a;
  55. const int& ar = a;
  56. ar = 5;//ошибка, константная
  57.  
  58. Константная ссылка - это нонсенс. Она по определению константная. Компилятор скорее всего выдаст предупреждение, что он проигнорировал const.
  59. int& const x; //не имеет смысла
  60.  
  61.  
  62.  
  63. Константный указатель
  64. Константный указатель — это указатель, значение которого не может быть изменено после инициализации. Для объявления константного указателя используется ключевое слово const между звёздочкой и именем указателя:
  65. int value = 7;
  66. int *const ptr = &value;
  67. Подобно обычным константным переменным, константный указатель должен быть инициализирован значением при объявлении. Это означает, что он всегда будет указывать на один и тот же адрес. В примере выше ptr всегда будет указывать на адрес value
  68. Но так как value - const, то ее значение может измениться через разыменовывание константного указателя:
  69.  
  70. int value = 7;
  71. const int *const ptr = &value;//константный указатель на константное значение, его нельзя перенаправить на другое значение, нельзя поменять значение того, на что он указывает
  72.  
  73. const int* ptr = &a; // указатель на константу
  74. ptr = &b; // ok
  75. ++(*ptr); // error: read-only variable is not assignable
  76. int* const cptr = &a; // константный указатель
  77. cptr = &b; // error: expression is not assignable
  78. ++(*cptr); // ok
  79. const int* const cc = &a; // константный
  80. // указатель на константу
  81.  
  82. Константный методы
  83. Константный метод — это метод, который гарантирует, что не будет изменять объект или вызывать неконстантные методы класса (поскольку они могут изменить объект).
  84. Чтобы сделать getValue() константным, нужно просто добавить ключевое слово const к прототипу функции после списка параметров, но перед телом функции:
  85. int getValue() const { return m_value; }
  86.  
  87.  
  88. Для методов, определённых вне тела класса, ключевое слово const должно использоваться как в прототипе функции в теле класса, так и в определении функции.
  89.  
  90. Обратите внимание, конструкторы не могут быть константными. Это связано с тем, что они должны иметь возможность инициализировать переменные-члены класса, а константный конструктор этого не может сделать. Следовательно, в С++ константные конструкторы запрещены.
  91.  
  92.  
  93.  
  94. Константные переменные
  95. В языке C++ появился ещё один способ — использование константных переменных, то есть переменных, которые нельзя изменять после инициализации. Рассмотрим на том же примере:
  96. const double PI=3.14; // здесь PI — константная переменная
  97. #define PI 3.14
  98.  
  99.  
  100.  
  101. Константные замыкания ТУТ ПРО ОБЫЧНЫЕ
  102. лямбда– — это удобный способ определения объекта анонимной функции ( замыкания) непосредственно в расположении, где оно вызывается или передается в качестве аргумента функции. Обычно лямбда-выражения используются для инкапсуляции нескольких строк кода, передаваемых алгоритмам или асинхронным методам.
  103. Лямбда-выражение начинается с предложения Capture (лямбда- знаком в стандартном синтаксисе), который указывает, какие переменные захватываются и является ли захват значением или ссылкой. Доступ к переменным с префиксом с амперсандом (&) осуществляется по ссылке, а к переменным без префикса — по значению.
  104. Пустое предложение фиксации ([ ]) показывает, что тело лямбда-выражения не осуществляет доступ к переменным во внешней области видимости.
  105.  
  106.  
  107.  
  108. Mutable
  109. Бывают случаи, когда строгое придерживание константности неудобно. Объект может оставаться логически константным ("logically const"), но при этом его физическая константность ("physically const") может быть нарушена.
  110. mutable означает, что спецификатор const, примененный к классу, следует игнорировать. По стандарту
  111. только данные класса могут быть mutable.
  112. Признак правильного использования mutable: если при доступе к данным через интерфейс класса все выглядит так, будто в классе ничего не менялось, то можно использовать mutable.
  113.  
  114. Ключевое слово mutable существует в стандарте языка С++ именно для решения данного класса проблем. Его можно добавить к переменным членам класса для указания того, что данная переменная может изменяться даже в константном контексте.
  115.  
  116. Есть и ещё один вариант применения ключевого слова mutable и он связан с сохранением состояния в лямбда-функциях. Обычно оператор вызова функции замыкания является константным. Другими словами — лямбда не может модифицировать переменные, захваченные по значению:
  117. о ключевое слово mutable может быть применено ко всей лямбда-функции, что сделает все её переменные изменяемыми:
  118.  
  119.  
  120. Стандартная библиотека C++
  121. STD
  122. По правилам языка C++ соответствующий компонент STD добавляется в программу путем включения заголовочного файла с помощью директивы:a
  123. #include <имя_файла>
  124. Основные компоненты STD:
  125. Language support library (языковая поддержка)
  126. Diagnostics library (исключения)
  127. General utilities library (утилиты)
  128. Strings library (строки)
  129. Localization library (локализация)
  130. Containers library (контейнеры)
  131. Iterators library (итераторы)
  132. Algorithms library (алгоритмы)
  133. Numerics library (числа)
  134. Input/output library (ввод/вывод)
  135. Regular expressions library (регулярные выражения)
  136. Atomic operations library (атомарные операции)
  137. Thread support library (многопоточность)
  138. STL состоит из двух основных частей: классы контейнеров и алгоритмы для работы с элементами контейнеров. Все компоненты STL являются шаблонами, поэтому их можно использовать для произвольных типов элементов, включая абстрактные.
  139. В STL выделяют пять основных компонентов:
  140. контейнер (container): управляет набором объектов в памяти.
  141. итератор (iterator): обеспечивает для алгоритма средство доступа к содержимому контейнера.
  142. алгоритм (algorithm): определяет вычислительную процедуру.
  143. функциональный объект (function object): инкапсулирует функцию в объекте для использования другими компонентами.
  144. адаптер (adaptor): адаптирует компонент для обеспечения различного интерфейса.
  145.  
  146.  
  147.  
  148. Ввод-вывод.
  149. #include <iostream>
  150. Библиотека iostream определяет три стандартных потока:
  151. cin стандартный входной поток
  152. cout стандартный выходной поток
  153. cerr стандартный поток вывода сообщений об ошибках
  154. Для ввода текста до символа перевода строки используется манипулятор потока getline():
  155. cin.getline(s, 80);
  156. endl Помещение в выходной поток символа конца строки '\n'
  157. get() Ожидает ввода символа
  158. getline(указатель, количество) Ожидает ввода строки символов. Максимальное количество символов ограничено полем количество
  159.  
  160.  
  161.  
  162. Контейнеры
  163. последовательные контейнеры — вектор (vector), двусвязный список (list), дэк (deque);
  164. ассоциативные контейнеры — множества (set и multiset ), хэш-таблицы (map и multimap);
  165. псевдо контейнеры — битовые маски (bitset), строки (string и wstring), массивы (valarray);
  166. ВЕКТОР
  167. размер вектора может динамически изменяться в любое время операциями добавления (метод push_back()) или удалении (например, метод pop_back()) элемента. Так же, как и для массива, мы можем обратиться к произвольному элементу вектора операцией индексации [ n ].
  168. Сет
  169. set<type_here> set_name_here;
  170. Set/map - красно-черное дерево
  171. Добавление/удаление элемента - O(logn)
  172. Поиск элемента - O(logn)
  173. Хранятся в порядке сортировки
  174. Set - множество уникальных элементов.
  175. #include <set>
  176. lower_bound - первый элемент, не меньше X
  177. upper_bound - первый элемент, больше X
  178. Мэп
  179. map - контейнер с ключами и значениями
  180. #include <map>
  181. std::map<std::string, int> a({
  182. {"aba", 2},
  183. {"aac", 17},
  184. {"za", 1},
  185. });
  186. MULTIMAP
  187. Содержит упорядоченные пары <ключ,значение>, где ключ и значение могут принадлежать к произвольным типам;
  188.  
  189. Элементы с любыми значениями ключа не должны быть уникальными, в упорядоченной последовательности элементов (по ключу) такие эквивалентные элементы представлены, как разные элементы, и располагаются они друг за другом;
  190. Поскольку ключи могут совпадать, то операция добавления новой пары в таблицу (метод insert()) всегда успешна. Поэтому нет смысла возвращать результат такой операции: возвращаемое значение — void;
  191.  
  192. Поскольку теперь в контейнере может находиться много элементов с равными ключами, то вводится дополнительный метод count(). Он получает параметром значение ключа, возвращает число вхождений элементов, имеющих такой ключ, в контейнер;
  193.  
  194. Операции удаления (метод erase()) с указанием ключа удаляемого элемента удаляет все сразу элементы с совпадающими ключами;
  195.  
  196. MULTISET
  197. multiset — это контейнер, который также будет содержать элементы в отсортированном порядке при добавлении, но он хранит повторяющееся элементы, по сравнению с множеством set. Часто его называют мультимножество.
  198.  
  199. INITIALIZER LIST
  200. std::vector<int> a({1, 2, 2, 5});
  201. // {..} - список инициализации
  202. // можно создать его явно
  203. std::initializer_list<int> b{1, 2, 3};
  204. // Потом от него можно создать какой-нибудь контейнер
  205. std::vector<int> c(b);
  206. // Больше он ничего не умеет :)
  207.  
  208. UNORDEREDMAP/SET
  209. #include <unordered_set>
  210. #include <unordered_map>
  211. unordered_set/unordered_map - хеш-таблица
  212. Добавление/удаление элемента - O(1)
  213. Поиск элемента - O(1)
  214. Unordered структуры умеют почти то же самое, что и set/map
  215.  
  216. LIST
  217. Что такое list в STL? Это такой контейнер (хранилище элементов одинакового типа), который представляет собой двусвязный список. Двусвязный список являет собой сущность, где каждый отдельный внутренний элемент имеет прямую связь со своими соседствующими элементами, при этом любые не соседствующие элементы друг с другом никаких связей не имеют и ничего друг о друге не знают.
  218. В отличие от других контейнеров для типа list не определена операция обращения по индексу или функция at(), которая выполняет похожую задачу.
  219. std::list<int> l({1, 2, 3, 4, 5});
  220. l.pop_back();
  221. l.pop_front();
  222. l.push_back(17);
  223. l.push_front(7);
  224.  
  225. Stl containers: queue, stack, deque
  226. #include <stack>
  227. #include <queue>
  228. queue - добавление в конец, удаление из начала за O(1)
  229. stack - добавление в конец, удаление с конца за O(1)
  230. deque - добавление/удаление в конец, добавление/удаление в
  231. начало, random access доступ за O(1)
  232.  
  233. #include <priority_queue>
  234. priority_queue - куча
  235. Добавление за O(logn)
  236. Получить максимум/минимум за O(1)
  237.  
  238. ТИПЫ ИТЕРАТОРОВ
  239. Рэндом аксес и обычный
  240. Рэндом у тех контейнеров, у которых есть []
  241. Рандом+5-5, форвард только вперед и все
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement