В C++ конструктор по умолчанию — это конструктор без параметров или с параметрами, у всех которых есть значения по умолчанию. Если в классе не объявлен ни один конструктор, компилятор автоматически сгенерирует public конструктор по умолчанию. Однако если объявлен хотя бы один любой другой конструктор (например, конструктор с параметрами), автоматически предоставленный компилятором конструктор по умолчанию уже не будет сгенерирован. Если в таком классе понадобится и конструктор по умолчанию, его нужно явно объявить (например, с помощью ClassName() = default;).
class Foo { public: Foo(int x) {} // Пользовательский конструктор // Foo() по умолчанию уже не будет сгенерирован компилятором! }; Foo f; // Ошибка компиляции — нет конструктора по умолчанию!
Чтобы явно создать конструктор по умолчанию в таком случае, следует добавить:
class Foo { public: Foo() = default; Foo(int x) {} };
«Если у вас есть только один конструктор с параметрами, можно ли создавать объекты этого класса без параметров? Почему?»
Ответ: Нет! Потому что, если объявлен любой конструктор, компилятор уже не добавляет автоматически конструктор по умолчанию. Для создания объектов без параметров нужно явно добавить конструктор по умолчанию в объявление.
История
На одном крупном проекте была написана иерархия классов для сериализации данных, где все "дочерние" классы имели только специфический конструктор с параметрами. После рефакторинга оказалось, что при использовании контейнеров STL (например, std::vector) с этими классами компиляция падала: контейнеру требовался конструктор по умолчанию, которого не было. Проблема решилась только после явного объявления конструктора по умолчанию.
История
В проекте, использующем шаблонизацию, один из классов-адаптеров объявил только конструктор с параметрами для передачи ресурсов. При этом, одна из библиотек требовала наличие конструктора по умолчанию для корректного функционирования (создавая временные объекты через типы шаблонов). Возникали таинственные ошибки линковки, которые долго не могли объяснить, пока не реализовали явный default constructor.
История
В коде встречалась миграция с C++98 на C++11, и попытка воспользоваться "= default" для явного объявления конструктора по умолчанию. На старых компиляторах возникали ошибки или игнорировались новые синтаксические конструкции. Это выявило, что не все разработчики понимают различие между явно реализованным конструктором по умолчанию, сгенерированным компилятором, и новым синтаксисом "= default".