TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #1095 3.27K
​​Дефолтный конструктор. Ограничения
#новичкам

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

1️⃣ У класса есть другие конструкторы

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


Даже если вы сами определили copy/move конструктор руками, конструктор по-умолчанию неявно генерироваться не будет:

struct UserCopyConstructor
{
UserCopyConstructor(const UserCopyConstructor&) {}
// UserCopyConstructor::UserCopyConstructor() is implicitly defined as deleted
};

struct UserMoveConstructor
{
UserMoveConstructor(UserMoveConstructor&&) = default;
// UserMoveConstructor::UserMoveConstructor() is implicitly defined as deleted
};


2️⃣ В классе есть нестатическое поле-ссылка.

Ссылка обязательно должна быть инициализирована объектом, а это невозможно сделать, не имея объект.

struct HasReference {
int& ref; // error: reference needs to be initialized
};


3️⃣ В классе есть нестатическое константное поле с тривиальным конструктором по-умолчанию. Тривиальные конструкторы по сути вообще ничего не делают, кроме как начинают лайфтайм объекта. То есть все поля заполняются мусором.

Но для константных объектов подразумевается наличие определенного постоянного значения. Мусорные значения не удовлетворяют этому требованию.

struct ConstTrivial {
const int x; // int has a trivial default constructor, so cannot default construct an object
};


Тем не менее, компилятор спокойно может проглотить константный член с нетривиальным дефолтным конструктором. Считается, что такой конструктор корректно инициализирует объект:

struct ConstNonTrivial {
const std::string s; // std::string has non-trivial constructor
};
ConstNonTrivial cnt; // OK, s is just empty string


4️⃣ Если какой-то член класса или базовый класс имеет недоступный (private) или удалённый (= delete) конструктор по умолчанию

struct NoDefault {
private:
NoDefault() {} // private constructor
};
struct Derived : NoDefault {
// Derived() is implicitly deleted
};


struct DeletedDefault {
DeletedDefault() = delete; // explicilty deleted
};
struct HasDeleted {
DeletedDefault dd;
};
HasDeleted hd; // ERROR! dd has explicilty deleted default constructor


Если знаете еще способы, пишите в комментах.

Don't be trivial. Stay cool.

#cppcore
  • ❤ 14
  • 🔥 7
  • 👍 3
  • 😁 2
  • ❤‍🔥 1
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →