avatar
Грокаем C++
@grokaemcpp
23.06.2026 10:00
Дефолтный конструктор. Введение
#новичкам

Описание корректного интерфейса создания объекта - важная часть проектирования класса. Поэтому надо понимать нюансики работы с конструкторами, чтобы все правильно организовать.

Ну и конечно самый базовый и, потенциально, самый сложный с точки зрения языка - конструктор по-умолчанию.

class NoConstructor {
int total;
public:
void accumulate (int x) { total += x; }
};

Example ex;


Казалось бы, у Example вообще не определено ни одного конструктора. Но тем не менее объект успешно создался. Как так?

Дефолтный конструктор умеет за вас генерировать сам компилятор.

А почему бы и нет? Смотря со стороны даже вполне логично и понятно, что он должен делать: вызывать конструкторы по умолчанию для всех нестатических членов и базовых классов в порядке объявления. Если мне от дефолтного конструктора нужно только это, то я могу просто положиться на компилятор.

Таким образом конструктор по-умолчанию входит в число специальных методов классов, которые компилятор сам умеет генерить.

Однако, не все так просто.

Как только вы определите хотя бы один другой конструктор, компилятор перестанет генерить дефолтный:

class ParametrizedConstructor {
int total;
public:
ParametrizedConstructor(int initial_value) : total(initial_value) { };
void accumulate (int x) { total += x; };
};
ParametrizedConstructor ex (100); // ok
ParametrizedConstructor ex1; // error: no default constructor


Оно и понятно: если вы не определяли никакой конструктор, значит вы довольны дефолтным поведением. Но как только вы сами определили конструктор, вы сказали компилятору, что дефолтное поведение вам не подходит и вы берете ответственность за способы создания объектов этого класса.

И компилятор не смеет перечить вашей задумке. Очень может быть, что вы хотите, чтобы Example2 создавался только через параметрический конструктор и больше никак. По сути, именно это и прописано сейчас в классе. Если бы компилятор неявно добавил конструктор по-умолчанию, то это нарушило бы контракт вашего класса.

Если вы все-таки хотите, чтобы у вас была возможность создать объект по-умолчанию, то вам явно нужно добавить конструктор без аргументов:

class ParametrizedAndDefaultConstructor {
int total;
public:
ParametrizedAndDefaultConstructor() = default; // или так
ParametrizedAndDefaultConstructor() {} // или так
ParametrizedAndDefaultConstructor(int initial_value) : total(initial_value) { };
void accumulate (int x) { total += x; };
};
ParametrizedAndDefaultConstructor ex(100); // ok
ParametrizedAndDefaultConstructor ex1; // ok


ParametrizedAndDefaultConstructor() = default; - вы явно определяете конструктор по-умолчанию, но так же явно просите компилятор о том, чтобы его поведение было как если бы сам компилятор его генерировал.

ParametrizedAndDefaultConstructor() {/something/} - это вы уже самостоятельно определяете, какую дополнительную логику должен иметь этот конструктор. Он делает все то же самое, что и тривиальный, только вдобавок выполняется еще и то, что вы указали внутри фигурных скобок. Такой конструктор называется уже нетривиальным, даже если его тело в итоге оказалось пустым.

О том, какую роль 50 оттенков конструктора по-умолчанию при обращении с объектами классов, мы поговорим в следующем посте.

Don't be trivial. Stay cool.

#cppcore
19
👍 13
🔥 6
❤‍🔥 1
24 15 3.1K

Обсуждение 24

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram

Грокаем C++

9.3K
Два сеньора C++ - Владимир и Денис - отныне ваши гиды в этом дремучем мире плюсов.

По всем вопросам (+ реклама) @ninjatelegramm

Менеджер: @Spiral_Yuri
Реклама: https://telega.in/c/grokaemcpp
Мы на TGstat: https://tgstat.ru/channel/@grokaemcpp/stat
Открыть в Telegram