-
Notifications
You must be signed in to change notification settings - Fork 0
CPP 04. Создание и уничтожение объектов в CPP. Конструкторы и деструкторы. Раздел инициализации конструкторов. Способы создания объектов. Явный и неявный вызов конструкторов. Приведение типа.
В любой момент времени все члены данного объекта должны быть определены.
По умолчанию создается 3 конструктора: без параметров (по умолчанию), копирования или переноса. Если реализован хотя бы один, то конструктор по умолчанию не создается, если задать явно конструктор копирования, конструктор переноса не создается. За уничтожение отвечает деструктор.
Конструктор - метод, который инициализирует объект класса.
Когда используется конструктор:
- Когда определяем объект
- Когда идёт приведение типов
- Когда передаем параметры в метод по значению или возвращаем по значению
- Когда динамически выделяем память, используя оператор new (явный вызов).
Свойства:
- отсутствует тип возврата
- можно перегружать
- не наследуется
- если private, то невозможно создание производных классов
- не может быть
volatile
,static
,const
,virtual
- может быть
constexpr
(вычисляется на этапе компиляции),explicit
(вызывается только явно) - если в классе не определяется явно ни одного конструктора, то создаются конструктор по умолчанию (без параметров) и конструктор копирования
- если мы указали хотя бы один конструктор, то конструктор по умолчанию не создаётся
- конструктор копирования создаётся всегда.
<имя класса>::<имя класса(конструктора)>([<Список параметров>])[:<раздел инициализации>] //отвечает за создание
{
тело конструктора // объект уже создан
}
Мы обязаны инициализировать в разделе инициализации:
- Базовые классы (если в базовых классах есть конструкторы по умолчанию, их можно не инициализировать, но если их нет, то мы обязаны явно вызвать конструкторы баз, они будут отрабатывать в том порядке, в котором мы их наследуем)
- Члены данных, если они являются объектами
- Константные члены объектов
При создании и во время работы объект может захватывать ресурсы, связи, может быть связан с другими объектами. Когда мы выходим из области видимости, объект уничтожается. В этом случае надо освободить ресурсы и оставить связи непротиворечивыми.
Деструктор - метод, который уничтожает объект класса.
Основной метод вызова деструктора - неявный. Начиная с C++17 можно явно вызывать деструктор полным квалификационным методом (с указанием имени класса, объекта)
Свойства:
- не может быть
const
,volatile
,static
- может быть
virtual
- не принимает параметров
- отсутствует тип возврата
- если явно не определить - создаётся по умолчанию
- не перегружается
- деструкторы вызываются в порядке, обратном порядку создания (по стеку)
В любом классе нужно явно определить:
- Конструктор по умолчанию
- Конструктор копирования
- Конструктор переноса
- Деструктор
- Оператор присваивания
После создания объекта сразу должна пройти его инициализация, для этого мы используем специальные методы – конструкторы. Его вызов может быть как явным, так и неявным. По умолчанию создается конструктор без параметров, конструктор копирования, и конструктор переноса. Конструктор – метод, который не имеет типа возврата, его имя совпадает с именем класса.
class A
{
private:
int a;
const int cb = 2;
static int sc;
static const int scd = 1;
public:
A(int i);
};
A::A(int i): a(i) //, cb(i), sc(i), scd(i)
{
a = i;
// cb = i; // Error
// sc = i; // Не относится к классу в общем
// scd = i; // Error
}
- Создание на стеке: объект создается прямо в функции или блоке кода, используя имя класса и операторы скобок.
- Создание на куче: объект создается с помощью оператора new, который выделяет память для объекта в куче и вызывает конструктор.
- Копирование объекта: объект может быть скопирован с помощью конструктора копирования, который создает новый объект с теми же значениями членов, что и у исходного объекта.
- Перемещение объекта: объект может быть перемещен с помощью конструктора переноса, который перемещает ресурсы из одного объекта в другой, не копируя их.
Явный вызов конструктора происходит при создании объекта с помощью оператора new и явного вызова конструктора.
Неявный вызов конструктора происходит при создании объекта без использования оператора new и явного вызова конструктора.
Неявный вызов чреват ошибкой.
Явно можно вызвать конструктор следующими способами:
<тип> <идентификатор> [(<параметры>)]; // A obj();
<тип> <идентификатор> {[<параметры>]};
<тип> *<идентификатор> = new <тип> {<параметры>};
<тип> <идентификатор> = <тип> {<параметры>};
Неявно:
<тип> <идентификатор> = <значение>;
<тип> <идентификатор> = {<параметры>};
Любой конструктор - оператор приведения типа.
В языке C++ указатель или ссылка на любой производный класс неявно приводится к указателю или ссылке на базовый. Если метод получает ссылку на базовый класс, можно в метод передать любой объект производного класса.