|
Пр. 1. ооп. Объектноориентированное программирование, поясните суть парадигмы, чем отличается от других. Расскажите про главные постулаты ооп
1. ООП. Объектно-ориентированное программирование, поясните суть
парадигмы, чем отличается от других. Расскажите про главные
постулаты ООП.
Объе́ктно-ориенти́рованное программи́рование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования. Парадигма это совокупность идей и понятий, определяющих стиль написания компьютерных программ (подход к программированию). Это способ концептуализации, определяющий организацию вычислений и структурирование работы, выполняемой компьютером.
Парадигмы бывают:
Императивное программирование Декларативное программирование Структурное программирование Функциональное программирование Логическое программирование Объектно-ориентированное программирование
Постулаты:
Инкапсуляция – Благодаря инкапсуляции внутренние детали класса могут быть скрыты снаружи. Он разрешает доступ к элементам класса извне только через интерфейс, предоставляемый классом.
Полиморфизм - Полиморфизм позволяет объектам с различными внутренними структурами иметь общий внешний интерфейс. Полиморфизм особенно эффективен при реализации наследования.
Абстракция в объектно-ориентированном программировании - это придание объекту характеристик, которые отличают его от всех объектов, четко определяя его концептуальные границы.
Наследование — один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с инкапсуляцией, полиморфизмом и абстракцией), позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом.
2. Класс и объект. Что такое класс и объект, чем отличаются. Как
объявляется класс и создается экземпляр класса.
Класс – тип данных, определяемый программистом.
Объект – это экземпляр класса или структура данных, содержащая описание свойств внешнего объекта программирования.
Каждый объект имеет:
· Идентичность, которая отличает его от других объектов в системе.
· Состояние, определяющее характерные свойства объекта, а также значения свойств, которые он содержит.
· Поведение, которое представляет внешне видимые действия, выполняемые объектом с точки зрения изменений в его состоянии.
Составляющие класса:
· Набор атрибутов для объектов, которые должны быть созданы из класса. Как правило, разные объекты класса имеют некоторые различия в значениях атрибутов. Атрибуты часто называют данными класса.
· Набор операций, которые отображают поведение объектов класса. Операции также называются функциями или методами.
3. Класс и объект. Поля и методы, параметры по умолчанию.
Методы — это функции, которые могут выполнять какие-либо действия над данными (свойствами) класса.
Поле класса в объектно-ориентированном программировании — переменная, описание которой создает программист при создании класса. Все данные объекта хранятся в его полях. Доступ к полям осуществляется по их имени. Обычно тип данных каждого поля задаётся в описании класса.
Параметр по умолчанию — это параметр функции, который имеет определённое (по умолчанию) значение и его необязательно указывать. Если пользователь не передаёт в функцию значение для параметра по умолчанию, то используется значение по умолчанию. Если же пользователь передаёт значение, то это значение используется вместо значения по умолчанию
Как только параметр по умолчанию объявлен, повторно объявить его уже нельзя.
4. Класс и объект. Модификаторы доступа.
В C++ есть 3 уровня доступа:
Все свойства и методы классов имеют права доступа. Для того, чтобы разрешить доступ к данным класса извне, используют модификатор доступа public. Все функции и переменные, которые находятся после модификатора public, становятся доступными из всех частей программы.
Закрытые данные класса размещаются после модификатора доступа private. Если отсутствует модификатор public, то все функции и переменные, по умолчанию являются закрытыми.
Обычно, приватными делают все свойства класса, а публичными — его методы. Все действия с закрытыми свойствами класса реализуются через его методы.
Модификатор protected (защищенный) указывает на то, что свойства и методы доступны только наследникам класса.
5. Класс и объект. Конструктор. По умолчанию, с параметрами, копирования.
Конструктор класса – это специальный метод (функция) класса.
• Вызывается в момент создания объекта
• Не имеет возвращаемого значения (даже тип void)
• Существует 3 типа конструкторов
Конструктор по умолчанию:
Конструктор, не требующий параметров, называется конструктором по умолчанию. Это может быть конструктор с пустым списком параметров или конструктор, в котором все аргументы имеют значения по умолчанию. Конструкторы могут быть перегруженными, но конструктор по умолчанию может быть только один.
имя_класса() { тело_конструктора }
Конструктор копирования:
Как правило, при создании нового объекта на базе уже существующего происходит поверхностное копирование, то есть копируются те данные, которые содержит объект-источник. При этом если в объекте-источнике имеются указатели на динамические переменные и массивы, или ссылки, то создание копии объекта требует обязательного дублирования этих объектов во вновь создаваемом объекте. С этой целью вводится конструктор копии, который автоматически вызывается во всех перечисленных случаях. Он имеет единственный параметр — ссылку на объект-источник:
имя_класса(имя_класса &) { тело_конструктора }
Конструкторы с параметрами
Хотя конструктор по умолчанию отлично подходит для обеспечения инициализации классов значениями по умолчанию, часто может быть нужно, чтобы экземпляры класса имели определённые значения. Конструкторы также могут быть объявлены с параметрами.
имя_класса(параметры) { тело_конструктора }
6. Класс и объект. Конструктор. Список инициализаторов и вызов
конструктора.
При объявлении переменной мы можем присвоить ей значение в этот же момент. Это называется инициализацией переменной.
C++ поддерживает два основных способа инициализации переменных:
Копирующая инициализация (или ещё «инициализация копированием») с помощью знака равенства =:
int nValue = 5; // копирующая инициализация
Прямая инициализация с помощью круглых скобок ():
int nValue(5); // прямая инициализация
Прямая инициализация может работать лучше с некоторыми типами данных, копирующая инициализация — с другими.
Прямая или копирующая инициализация работают не со всеми типами данных (например, вы не сможете использовать эти формы для инициализации списка значений).
Конструктор нельзя вызвать как обычный метод. Конструктор по умолчанию вызывается, если пользователем не указаны значения для инициализации.
Вызов конструктора по умолчанию:
Point p;
p.print();
Вызов конструктора с параметрами:
Point p1(2, 5);
p1.print();
Вызов конструктора копирования:
Point p2(&p1);
p2.print();
7. Класс и объект. Конструктор. Спецификаторы default и delete.
Полезность данного спецификатора весьма спорная: кто-то найдет его полезным, а кому-то он покажется бесполезным. Так или иначе, суть его заключается в том, что пользователь может указать компилятору реализовать ту или иную функцию-член класса по - умолчанию:
<Название класса>() = default;
Вместо определения конструктора без параметров появилась возможность просто указать компилятору сгенерировать его по - умолчанию. (Тупыми словами если у тебя уже есть конструктор с параметрами, но тебе каким-то хреном нужен конструктор по умолчанию то тебе нужно создать этот конструктор и указать =default)
Спецификатор delete предназначен для пометки методов, которые не должны вызываться:
8. Класс и объект. Деструктор. Как объявляется и для чего нужен.
Деструктор - особый метод, который вызывается автоматически при уничтожении объекта.
Не имеет типа возвращаемого значения. Не имеет параметров. Вызывается неявно при уничтожении объекта. Необходим при динамическом выделении памяти
Объявление:
имя_класса () { тело_деструктора }
point(){}
Когда объект автоматически выходит из области видимости или динамически выделенный объект явно удаляется с помощью ключевого слова delete, вызывается деструктор класса (если он существует) для выполнения необходимой очистки до того, как объект будет удалён из памяти. Для простых классов (тех, которые только инициализируют значения обычных переменных-членов) деструктор не нужен, так как C++ автоматически выполнит очистку самостоятельно.
Однако, если объект класса содержит любые ресурсы (например, динамически выделенную память или файл/базу данных), или, если вам необходимо выполнить какие-либо действия до того, как объект будет уничтожен, деструктор является идеальным решением, поскольку он последнее, что происходит с объектом перед его окончательным уничтожением.
9. Класс и объект. Указатель this.
Указатель this хранит адрес объекта, для которого вызван метод. Его невозможно переопределить.
Пример:
point (int x, int y) {
this->x = x;
this->y = y; }
Ключевое слово this представляет собой неявно определенный указатель на сам объект. С его помощью метод класса определяет, с данными какого объекта ему предстоит работать.
При вызове метода ему передается неявный аргумент, содержащий адрес объекта, для которого эта функция вызывается.
Использование this необходимо в функциях, которые непосредственно работают с указателем на объект:
1. this – указатель на объект (адрес объекта)
2. *this – разыменованый указатель (сам объект)
Указатель this удобно использовать, например, в конструкторах, когда имена передаваемых параметров совпадают с именами полей класса.
В случае если аргументы и поля класса имеют разные имена, указатель this при обращении к полям класса может быть опущен
10. Класс и объект. Перегрузка операций.
Перегрузка (или переопределение) операций – это возможность применять встроенные операторы языка к разным типам, в том числе и пользовательским.
Синтаксически перегрузка операций осуществляется следующим образом:
тип operator @ (список_параметров-операндов) { тело функции }
где @ — знак перегружаемой операции (-, +, * и т.д.), тип — тип возвращаемого значения.
Тип возвращаемого значения должен быть отличным от void, если необходимо использовать перегруженную операцию внутри другого выражения.
В C++17 стандарт разрешает перегружать следующие операторы: +, -, *, /, %, ^, &, |, , !, ,, =, <, >, <=, >=, ++, –-, <<, >>, ==, !=, &&, ||, +=, -=, /=, %=, ^=, &=, |=, *=, <<=, >>=, [], (), ->, ->*, new, new[], delete, delete[]. (Обратим внимание на то, что этот список не менялся с C++98.) Последние четыре оператора, связанные с распределением памяти, в данной статье не рассматриваются, эта довольно специальная тема будет рассмотрена в следующей статье. Остальные операторы можно разделить на унарные, бинарные и оператор (), который может иметь произвольное число параметров. Операторы +, -, *, &, ++, –- имеют два варианта (иногда семантически совершенно разных) — унарный и бинарный, так, что фактически перегружаемых операторов на 6 больше.
При перегрузке операторов надо стараться, чтобы смысл перегруженного оператора был очевиден для пользователя. Хороший пример перегрузки в этом смысле — это использование операторов + и += для конкатенации экземпляров std::basic_string<>. Оригинальное решение используется в классе std::filesystem::path (C++17). В этом классе операторы / и /= перегружены для конкатенации элементов пути. Конечно к делению это никакого отношения не имеет, но зато этот символ оператора совпадает с традиционным разделителем элементов пути. Запоминается с первого раза. Необходимо учитывать приоритет и ассоциативность операторов, они при перегрузке не меняются и должны соответствовать ожиданиям пользователя. Характерный пример — это использование оператора <<для вывода данных в поток. К сожалению, приоритет этого оператора довольно высок, поэтому скобками приходится пользоваться чаще, чем хотелось бы. Не рекомендуется перегружать следующие три бинарных оператора: , (запятая), &&, ||.
11. Класс и объект. Статические поля и методы, особенности работы.
Static - это ключевое слово в C++, используемое для придания элементу особых характеристик. Для статических элементов выделение памяти происходит только один раз и существуют эти элементы до завершения программы.
Статическое поле существует в единственном экземпляре для всех объектов класса на всем протяжении работы программы.
Похожи на глобальные переменные. Можно получить доступ без создания объекта. описываются с помощью ключевого слова static, которое может использоваться при объявлении.
static тип имя_поля;
Статические методы можно вызывать по имени класса
не должны задействовать не статические поля. не имеют доступа к указателю this.
static тип имя_метода(аргументы);
Статические член-данные (или поля) класса можно рассматривать как глобальную переменную класса. Но в отличие от обычных глобальных переменных на статические члены распространяются правила видимости private и public. Поместив статическую переменную в часть private, можно ограничить ее использование.
Объявление статического члена в объявлении класса не является определением, то есть это объявление статического члена не обеспечивает распределения памяти и инициализацию.
Инициализация статических полей
Статические поля нельзя инициализировать в теле класса, а также в методах. Статические поля должны инициализироваться аналогично глобальным переменным в области видимости файла.
12. Класс и объект. Модификатор const для полей и методов, особенности работы.
Квалификатор типов const – зарезервированное ключевое слово в языке программирования С++, которое не даёт модифицировать значения переменных. Отсюда и возникло в
программировании такое понятие, как константы или константные переменные, то есть неизменные. Необходимо запомнить, что при объявлении константы, её нужно инициализировать.
Константное поле – поле которое невозможно изменить после
инициализации, обязательно должно быть проинициализировано.
const тип ИМЯ_ПОЛЯ;
Константный аргумент – аргумент, который невозможно изменить в теле
метода (указатель или ссылка).
тип имя_метода(const тип имя_аргумента);
Константный метод – метод, который не может изменять
поля своего класса.
тип имя_метода(аргументы) const;
Объекты классов можно сделать константными (используя ключевое слово const). Инициализация выполняется через конструкторов классов.
const Date date1;
Как только константный объект класса инициализируется через конструктор, то любая попытка изменить переменные-члены объекта запрещена, так как это нарушает принципы константности объекта. Запрещается как изменение переменных-членов напрямую (если они являются public), так и вызов методов (сеттеров), с помощью которых можно установить значения переменным-членам.
13. Наследование. Базовый класс и потомок. Спецификатор final.
Наследование — это механизм создания нового класса на основе уже существующего. При этом к существующему классу могут быть добавлены новые элементы (данные и функции), либо существующие функции могут быть изменены. Наследование позволяет сократить дублирование кода и создавать иерархию классов с повторно используемой функциональностью.
Иерархия классов позволяет определять новые классы на основе уже имеющихся
- Имеющийся класс называется базовым, порождающим, родительским или суперклассом
- Новый класс называют производным, потомком, порожденным
- Классы потомки получают «наследство» - данные и методы своих базовых классов, а также могут быть расширены своими собственными.
- При наследовании потомок «включает» в свою реализацию базовый класс
При наследовании некоторые имена методов (функций-членов) и полей (данных-членов) базового класса могут быть по-новому определены в производном классе. В этом случае соответствующие компоненты базового класса становятся недоступными из производного класса. Для доступа из производного класса к компонентам базового класса, имена которых повторно определены в производном, используется операция разрешения контекста:
Синтаксис:
class имя_класса : [модификатор] имя_базового_класса
{
тело_класса
};
Общее наследование:
Общее наследование означает, что порожденный класс – это подтип базового класса. Таким образом, порожденный класс представляет собой модификацию базового класса, которая наследует общие и защищенные члены базового класса.
Спецификатор final:
Конечное ключевое слово можно использовать для обозначения виртуальных функций, которые нельзя переопределить в производном классе. Можно также использовать это ключевое слово для назначения классов, которые невозможно наследовать.
14. Наследование. Модификаторы доступа.
При объявлении порождаемого класса модификатор доступа может принимать значения public, private, protected либо отсутствовать, по умолчанию используется значение private. В любом случае порожденный класс наследует все члены базового класса, но доступ имеет не ко всем. Ему доступны общие (public) члены базового класса и недоступны частные (private).
При общем наследовании порожденный класс имеет доступ к наследуемым членам базового класса с видимостью public и protected. Члены базового класса с видимостью private – недоступны.
Спецификация доступа:
| внутри класса
| в порожденном классе
| вне класса
| private
| +
| -
| -
| protected
| +
| +
| -
| public
| +
| +
| +
| 15. Наследование. Не наследуемые методы.
Методы, которые не наследуются: конструкторы, деструктор, оператор =, а также дружественные функции, т.к. не являются компонентами класса.
Конструкторы и деструкторы:
- Если в базовом классе нет конструкторов или существует без аргументов (или с аргументами по умолчанию), то в производном классе конструктор можно не писать
- Если в базовом классе все конструкторы с аргументами, тогда наследник должен иметь конструктор и явно вызывать конструктор базового класса.
- Конструктор базового класса вызывается в списке инициализаторов (другого способа нет)
Point3D(int x, int y, int z) : Point2D(x, y){}
- Что бы синтаксис был более последователен, было решено интерпретировать встроенные типы, словно у них есть конструктор с одним аргументом (является хорошим тоном)
Point3D(int x, int y, int _z):Point2D(x, y), z(_z){}
- При создании объекта, первым вызывается конструктор базового класса, после этого конструктор производного
- При отсутствии деструктора, компилятор создает его автоматически
- Деструктор базового класса вызывается автоматически (всего один и без параметров)
- Вызывается в обратном порядке созданию (первым деструктор производного класса, следующим деструктор базового класса).
16. Наследование. Перекрытие методов.
Если в базовом классе существует поле с таким же именем, как и в производном, происходит перекрытие полей. Что бы обратиться к полю базового класса, необходимо указать полное имя.
Аналогично при перекрытии методов (методы перекрываются, а не перегружаются в данном случае) using (имя класса)::(метод).
17. Наследование. Конструкторы, деструкторы и перегруженные операторы (см вопрос 15)
Конструкторы и деструкторы не наследуются.
• Если в базовом классе нет конструкторов или существует без аргументов (или с аргументами по умолчанию), то в производном классе конструктор можно не писать
• Если в базовом классе все конструкторы с аргументами, тогда наследник должен иметь конструктор и явно вызывать конструктор базового класса.
• При создании объекта, первым вызывается конструктор базового
класса, после этого конструктор производного
• При отсутствии деструктора, компилятор создает его автоматически
• Деструктор базового класса вызывается автоматически (всего один и без параметров)
• Вызывается в обратном порядке созданию (первым деструктор производного класса, следующим деструктор базового класса).
Перегруженные операторы (т.к. являются методами) наследуются по общим правилам, за исключением оператора= (он не наследуется).
18. Наследование. Статические поля и методы, Спецификатор finale
- Статические поля и методы и перегруженные операторы (т.к. являются методами) наследуются по общим правилам
- Статические поля становятся едиными для всех объектов базового и производного классов
Про спецификатор final см. вопрос 13.
19. Множественное наследование. Прямой и косвенный базовый класс.
Наличие нескольких прямых базовых классов называют множественным наследованием. - Непосредственный (прямой) базовый класс – если он входит в список базовых при определении.
- Косвенный или непрямой – служит базовым для классов входящих в список базовых.
- Класс может быть использован более одного раза в качестве косвенного базового класса.
- При наследовании ни один класс не может быть использован более одного раза в качестве непосредственного базового.
- Для устранения дублирования необходимо базовый класс определить
как виртуальный (virtual): class X : virtual public Y {};
Виртуальная функция становится виртуальной до конца иерархии, а ключевое слово virtual является «ключевым» только в первый раз, а в последующие разы оно несет в себе чисто информативную функцию для удобства программистов.
20. Абстрактные классы. Полиморфизм.
Абстрактный класс – это класс, который содержит чистые виртуальные функции.
• Нельзя создать объект абстрактного класса
• Содержит хотя бы одну чистую виртуальную функцию.
Слово полиморфизм означает наличие многих форм. Как правило, полиморфизм возникает, когда существует иерархия классов, и они связаны наследованием.
Полиморфизм C ++ означает, что вызов функции-члена вызовет выполнение другой функции в зависимости от типа объекта, который вызывает эту функцию. Пример – конструктор наследника вызывает конструктор родителя
Синтаксис: (абстрактный класс)
class имя_класса
{
...
virtual тип имя_метода(аргументы) = 0;
...
};
21. Абстрактные классы. Виртуальные методы, чистые виртуальные методы и спецификатор override.
Виртуальные функции – реализация динамического связывания. Позволяют вызывать реализацию в зависимости от объекта.
В C++ виртуальные методы объявляются путем добавления ключевого слова virtual к объявлению функции в базовом классе. Этот модификатор наследуется всеми реализациями этого метода в производных классах, а это означает, что они могут продолжать перегружать друг друга и опаздывать.
Синтаксис:
class имя_класса
{
virtual тип имя_метода(аргументы);
};
Чистые виртуальные функции – не содержат реализации.
class имя_класса
{
...
virtual тип имя_метода(аргументы) = 0;
...
};
override – указывает, что метод класса потомка переопределяет метод
родительского класса. (По тупому компилятору это ключевое слово говорит искать метод потомка в родителе так как она виртуальная, но если в родителе её нет, то выдаст ошибку, а без этого ключевого слова компилятор просто воспримет как новый метод)
- Указывается в классе потомке
- Позволяет предотвратить ошибки при переопределении
Для переопределения виртуальной функции в производном классе она должна быть определена с ключевым словом override, которое помещается после списка параметров функции.
class имя_класса : имя_базового_класса
{
...
тип имя_метода(аргументы) override;
...
};
22. Абстрактные классы. Раннее и позднее связывание.
Связывание — это сопоставление вызова функции с вызовом. В C++ все функции по умолчанию имеют раннее связывание, то есть компилятор и компоновщик решают, какая именно функция должна быть вызвана, до запуска программы. Виртуальные функции имеют позднее связывание, то есть при вызове функции нужное тело выбирается на этапе выполнения программы.
Встретив ключевое слово virtual, компилятор помечает, что для этого метода должно использоваться позднее связывание: для начала он создает для класса таблицу виртуальных функций, а в класс добавляет новый скрытый для программиста член — указатель на эту таблицу.
23. Шаблоны классов.
Шаблон класса – инструкция компилятору для создания класса. Класс создается на основе шаблона во время создания экземпляра класса.
В шаблоне может быть несколько параметров, могут задаваться параметры по умолчанию.
Шаблон можно специализировать, создать версию шаблона для конкретных аргументов с отличающейся логикой.
В угловых скобках мы указываем typename, это значит, что мы не знаем переменную какого типа данных мы буем использовать. Потом мы указываем тип данных в мейне.
Синтаксис:
template //указываем, что класс шаблонный, временная переменная
class имя_класса {};
template <- myClass.h
class myClass{
T value;
};
myClass obj; <- main.cpp
24. Исключения. Ключевые слова try, throw, catch.
Механизм обработки исключений – объектно-ориентированные средства
обработки ошибок.
Исключения обеспечивают способ передачи контроля из одной части программы в другую. Обработка исключений C ++ построена на трех ключевых словах: try, catch и throw .
try – контролируемый блок кода, блок try идентифицирует блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков catch:
throw – генерация исключения, программа выдает исключение, когда возникает проблема:
catch – перехват и обработка исключения, программа выхватывает исключение с обработчиком исключений в месте в программе, где вы хотите справиться с этой проблемой:
Стандартные исключения:
- В языке существует класс исключений и иерархия стандартных исключений. Мы можем создавать свои классы исключений на базе стандартных.
- В библиотеке содержатся функции для работы с исключениями и базовый класс std::exception
- В библиотеке < stdexcept > содержатся другие классы наследники базового std::exception
25. Исключения. Передача параметров. Порядок обработки исключений
При выбрасывании исключения (оператор throw), точка выполнения программы немедленно переходит к ближайшему блоку try. Если какой-либо из обработчиков catch, прикреплённых к блоку try, обрабатывает этот тип исключения, то точка выполнения переходит в этот обработчик и, после выполнения кода блока catch, исключение считается обработанным.
Если подходящих обработчиков catch не существует, то выполнение программы переходит в следующий блок try. Если до конца программы не найдены соответствующие обработчики catch, то программа завершает своё выполнение с ошибкой исключения.
26. Лямбда-выражения.
Лямбда-выражения или анонимные функции — это блоки кода с параметрами, которые можно вызвать из другого места программы. Они называются анонимными, потому что в отличие от функций, у них нет имён.
Лямбда состоит из трех частей: списка захвата [], необязательного списка параметров () и тела {}, все из которых могут быть пустыми:
[] список захвата. По умолчанию переменные охватывающей области недоступны лямбдой. Захват переменной делает ее доступной внутри лямбда, либо в виде копии, либо в качестве ссылки. Захваченные переменные становятся частью лямбда; в отличие от аргументов функции, они не должны передаваться при вызове лямбда. Основной синтаксис: [&] — захват по ссылке, все переменные в автоматическом хранилище объявлены в области охвата
[=] — захват по значению, значение копируется
[x, & y] — явно захватывает x по значению, а y по ссылке
() список параметров, который почти такой же, как и в обычных функциях. Если лямбда не принимает аргументов, эти круглые скобки могут быть опущены.
{} - это тело , такое же, как и в обычных функциях.
auto f = [](){};
27.Стандартная библиотека. Состав и назначение.
Стандартная библиотека языка программирования — набор модулей, классов, объектов, констант, глобальных переменных, шаблонов, макросов, функций и процедур, доступных для вызова из любой программы, написанной на этом языке и присутствующих во всех реализациях языка.
Стандартная библиотека шаблонов STL («Standard Template Library») — это часть стандартной библиотеки С++, которая содержит набор шаблонов контейнерных классов (например, std::vector и std::array), алгоритмов и итераторов. Изначально она была сторонней разработкой, но позже была включена в Стандартную библиотеку С++. Если вам нужен какой-нибудь общий класс или алгоритм, то, скорее всего, в стандартной библиотеке шаблонов он уже есть. Положительным моментом является то, что вы можете использовать эти классы без необходимости писать и отлаживать их самостоятельно (а ещё и разбираться в том, как они реализованы) + вы получаете достаточно эффективные (и уже много раз протестированные) версии этих классов. Проще говоря, мы не создаем что-то новое, а используем что-то уже придуманное, это облегчает нашу работу.
STL включает в себя:
Контейнеры(Классы, которые помогают хранить или управлять данными) Итераторы(Классы, которые позволяют управлять данными в контейнерах) Алгоритмы(какие-то функции, созданы для работы с контейнерами).
28. STL. Контейнеры.
В STL контейнеры могут быть последовательными или ассоциативными, а
также существуют контейнеры-адаптеры.
array - массив фиксированного размера, не имеет конструкторов и
закрытых членов (агрегатный тип) С++11.
vector - массив переменного размера, автоматически расширяется при
необходимости. Занимает больше места в отличии от array (выделяется
память для будущего роста).
deque – двусторонняя очередь, позволяет быстро вставлять/удалять
элементы с начала и с конца. В отличии от vector элементы не хранятся
непрерывно и не выделяется место для будущего увеличения (хранение по
типу списка).
list – двусвязный список, позволяет быстро вставлять/удалять элементы из
любой позиции. Доступ к произвольному элементу затратен (элементы не
хранятся последовательно).
forward_list – односвязный список, в отличии от list не поддерживает
двустороннее итерирование. С++11
set – контейнер содержащий упорядоченное множество
уникальных элементов.
multiset – контейнер содержащий упорядоченное множество элементов,
могут встречаться одинаковые элементы.
map – контейнер содержащий упорядоченное множество
уникальных элементов, элемент составляет пара «ключ-значение».
Сортировка в соответствии с установленным правилом для ключа.
multimap – контейнер содержащий упорядоченное множество
неуникальных элементов.
Контейнеры с приставкой unordered_ - это неупорядоченные
ассоциативные контейнеры (хеш-таблицы)
29. STL. Итераторы.
Для начала использования нужно подключить библиотеку <iterator> хотя это не обязательно
Итератор обеспечивает доступ к элементам коллекции, является
шаблонным классом.
Для каждого типа контейнеров существует своя реализация семейства
Итераторов.
Дополнительно существуют:
• Константные итераторы – запрещено изменять элементы,
• Реверсивные итераторы – для обхода в обратном направлении.
Для того чтобы понять как это работает можно привести пример с вектором:
Мы создаем вектор, вектор состоит из 4 элементов, и создаем два итератора на начало и на конец вектора. Т.е. первый итератор beginуказывает на начало, а второй итератор end на конец. И эти два итератора позволяют нам перемещаться по вектору вперёд, назад. И для того чтобы получить итератор мы обращаемся к нашему вектору, и вызываем необходимыми методами.
std::vector::iterator it;
30. STL. Алгоритмы.
STL содержит большой набор различных алгоритмов.
Все алгоритмы можно разделить на следующие типы:
Не модифицирующие – алгоритмы, не изменяющие последовательность и значения элементов.
Модифицирующие – изменяют значение элементов.
Алгоритмы удаления – специальная разновидность модифицирующих алгоритмов для удаления элементов.
Перестановочные алгоритмы – изменяют порядок элементов, но не изменяют значения.
Алгоритмы сортировки – специальный класс перестановочных алгоритмов.
Численные алгоритмы – объединяют числовые значения
контейнеров различными способами.
Все алгоритмы работают через итераторы:
- библиотека алгоритмов
- некоторые алгоритмы для работы с числами
- иногда в алгоритмах используют функциональные объекты.
31. STL. Функторы.
Функторы, функциональные объекты – это сокращение от функционального объекта, представляющий собой конструкцию, позволяющую использовать объект класса как функцию. В C++ для определения функтора достаточно описать класс, в котором переопределена операция ().
class functor {
public:
void operator(){ ... }
}
functor f;
f();
- Функциональный объект может быть более интеллектуальным, обладать большими возможностями, т.к. у него есть состояние
- Функциональный объект имеет свой тип, можно передавать как
параметр, создавать иерархию, а также функтор обладает всеми преимуществами классов
- Функциональный объект работает быстрее чем указатель на функцию.
Предикаты – это функции или функциональные объекты,
возвращающие булево значение (или приводимое к bool).
Функциональный адаптер – это функции или функциональные
объекты, возвращающие булево значение (или приводимое к bool). |
|
|