Лекция 7. ООП. Абстракция. Инкапсуляция
Абстракция
- Абстракция — придание объекту характеристик, которые чётко определяют его концептуальные границы, отличая от всех других объектов.
- Основная идея: отделить способ использования составных объектов данных от деталей их реализации в виде более простых объектов.
Инвариант
- Инвариант в ООП — выражение, определяющее непротиворечивое внутреннее состояние объекта.
- Должен сохраняться между вызовами публичных методов класса.
Class
- Класс — универсальный, комплексный тип данных, состоящий из тематически единого набора «полей» (переменных) и «методов» (функций для работы с этими полями).
- Является моделью информационной сущности с внутренним и внешним интерфейсами для оперирования своим содержимым.
Инкапсуляция
- Механизм языка, позволяющий ограничить доступ одних компонентов программы к другим.
- Языковая конструкция, позволяющая связать данные с методами, предназначенными для обработки этих данных.
Access Modifiers (модификаторы доступа)
- Public — доступно всем.
- Protected — доступно классу и его наследникам.
- Private — доступно только классу.
Constructor (конструктор)
- Специальный, не статический метод, используемый для инициализации объекта (обеспечивает инвариант).
- Название этого метода совпадает с именем класса.
- Не имеет возвращаемого типа.
Виды конструкторов:
- Default constructor (без аргументов):
- Если нет ни одного конструктора, то дефолтный = умолчательный (компилятор сгенерирует сам).
- Если объявлен хотя бы один конструктор (любой), а дефолтный — нет, компилятор его уже не смастерит (даже не скомпилится конструирование без аргументов).
- Если в любом converting-конструкторе все аргументы сделать аргументами по умолчанию — используется как дефолтный в случае необходимости.
- Converting constructor (из других типов).
- Copy constructor — создаёт такой же объект (передача объекта через константную ссылку:
T(const T&)). - Move constructor — передаёт значение, а сам зануляется/инвалидируется; используются rvalue ref (
T(T&&)) — будут разбираться во втором семестре подробно.
Порядок инициализации полей класса — в том же порядке, что и их декларация (объявление). Сделано это для того, чтобы деструктор работал однозначно (а работает он строго противоположно конструктору).
Method
const-метод — гарантия, что переменные-члены не изменятся внутри метода:int getValue() const;- В
const-методе нельзя менять состояние объекта; нельзя вызывать неконстантные методы для константных объектов.
Destructor (деструктор)
- Имя:
~ClassName(). - Вызывается при уничтожении объекта.
- Обычно используется для освобождения ресурсов.
operator= (оператор присваивания)
- Принимает
const T&, возвращаетT&. - Важна проверка на самоприсваивание (
if (this == &other) return *this;). - Важно освобождение данных в объекте, которому присваиваем, если это необходимо (
new/delete).
MyClass& operator=(const MyClass& other) {
if (this == &other) return *this;
// освободить старые данные
// скопировать новые данные
return *this;
}
Ключевое слово default
- Указывает компилятору самостоятельно сгенерировать соответствующую функцию класса.
- Применимо к: конструктору по умолчанию, конструктору копирования, конструктору перемещения, операторам присваивания (копированием и перемещением), деструктору.
MyClass() = default;
Ключевое слово delete
- Позволяет явно отказаться от использования стандартного конструктора/метода.
- Введено с C++11.
MyClass(const MyClass&) = delete; // запрет копирования
Геттеры
- Методы, возвращающие значения каких-то полей класса.
- Обычно объявляются как
const.
Ключевое слово explicit
- Используется для предотвращения неявных преобразований при вызовах функций.
class MyClass {
public:
explicit MyClass(int x);
};
MyClass obj = 5; // ошибка: неявное преобразование запрещено
MyClass obj(5); // OK
Special Members — таблица генерации компилятором
| Объявлено пользователем | default constructor | destructor | copy constructor | copy assignment | move constructor | move assignment |
|---|---|---|---|---|---|---|
| Ничего | defaulted | defaulted | defaulted | defaulted | defaulted | defaulted |
| Любой конструктор | not declared | defaulted | defaulted | defaulted | defaulted | defaulted |
| Default constructor | user declared | defaulted | defaulted | defaulted | defaulted | defaulted |
| Destructor | defaulted | user declared | defaulted | defaulted | not declared | not declared |
| Copy constructor | not declared | defaulted | user declared | defaulted | not declared | not declared |
| Copy assignment | defaulted | defaulted | defaulted | user declared | not declared | not declared |
| Move constructor | not declared | defaulted | deleted | deleted | user declared | not declared |
| Move assignment | defaulted | defaulted | deleted | deleted | not declared | user declared |
Rule of Three
Если определён хотя бы один из трёх методов, то надо определить все три:
- Destructor
- Copy constructor
- Copy assignment operator
Rule of Five (C++11+)
Если определён хотя бы один из пяти методов, то надо определить все пять:
- Destructor
- Copy constructor
- Copy assignment operator
- Move constructor
- Move assignment operator
Rule of Zero: лучше всего проектировать классы так, чтобы не определять ни одного из этих методов вручную, а полагаться на корректные члены-классы (умные указатели, контейнеры и т.п.).