TGViewer
this->notes. this->notes. @thisnotes · 4.52K subscribers
Post #210 1.23K
#cpp

Инициализация 1/2.

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

Первый пример:

int i;
return i; // ub

struct S {
int x;
};
S s;
return s.x; // ub


Это default initialisation, что вообще-то немного путает, потому что переменная у вас не инициализируется ничем дефолтным (мусор я бы дефолтным не назвал). Можно поправить так:

S() : x(0) {}

Это member initialiser list. Не оч удобно, потому что надо повторять во всех конструкторах, потому в C++11 появился

struct S {
int x = 0; // default member initialiser
};


Наверное использовать dmi может быть хорошим советом, пусть и не лишённым проблем.
Далее:

int i = 2; // copy initialisation

Такой же способ инициализации используется, когда вы передаёте аргумент в функцию по значению или по значению возвращаете. Если тип инициализируемого объекта и значения справа от = не совпадают, будет произведена некоторая цепочка преобразований типов (насколько я понимаю, сколько угодно стандартных преобразований и может быть одно пользовательское, всё это в произвольном порядке, конечно).
Помните, что copy init это никогда не operator=.

Aggregate init:

int i[3] = {1, 2, 3};
int i[] = {1, 2, 3};

struct S { int x; int y; };
auto s{1, 2};


Агрегатная инициализация будет copy-инициализировать каждый из переданных аргументов. У такого init есть фича:

struct S { int x; int y; };
S s = {1};
return s.y; // какое значение? ub?


Если вы опускаете часть аргументов при использовании агрегатной инициализации, остальные будут zero initialisated. Т.е. у вас никогда при таком способе не будет неинициализированных данных. Потому и работает вот такой способ заполнения массивов нулями:

int a[10] = {};

Ещё тут есть такая фича как brace elision.

Далее static initialisation:

static int i = 1; // constant initialisation
static int j; // zero initialisation


Все эти способы были просто унаследованы плюсами от C. Теперь про плюсовые.

Direct initialisations (whenever the initialiser is an argument list in parens):

S s(1, 2); // constructor
int i(3); // also for built-in type


Для built-in типов никакой разницы от copy init, но для остальных это возможность передать более одного аргумента при инициализации и отсутствие цепочки преобразований (просто вызов конструктора по всем правилам перегрузок). Тут стоит быть осторожным:

struct S {
explicit S(int) {}
S(double) {}
};
S s1 = 1; // S(double)
S s2(2); // S(int)


Value init (whenever the initialiser is a pair of empty parens):

int f() { return int(); }

Если есть пользовательский default ctor, то вызовется он, иначе zero init. Тут можно словить всякие маслины. Осторожно.

Uniform init — способ универсальной инициализации из C++11 (с помощью {}). Тут же появились list inits:

S s{1, 2}; // direct list init
S s = {1, 2}; // copy list init


И тут же появился std::initializer_list. Думаю, как им пользоваться вы знаете, так что опустим. Про его проблемы можно глянуть тут.
Для агрегатов list init это agregate init. Для built-in типов пример выше. Для классов либо вызов подходящего конструктора, либо direct/copy init.
{} — особый случай. Это дефолтный ктор, иначе ктор от initializer_list, иначе value init ☺️🎧
При list init никаких narrowing conversions не происходит, так что int i{1.0} не закатит.

Ну и опуская всякое неинтересное, не забудем про C++20 designated initialisation:

struct S { int x; int y; };
S s{.x = 1, .y = 2};


Подробнее со всякими интересными примерами можете посмотреть в доклад Тимура Думлера.

Тут мы упомянули даже не всё что на гифке. А на гифке тоже пары штук не хватает🙂
  • 👍 6
  • 🤯 2
More from @thisnotes
  1. Sep 17, 2026#common Сидите вы себе спокойно, разрабатываете поиск каких-нибудь объектов. Может это тов…
  2. Sep 9, 2026#cpp #books Да, книга 2001ого года. Мы ровесники. И да, в ней в основном обсуждаются какие…
  3. Sep 2, 2026#perf Попробовал собрать в кучку (кажется, немного сумбурно всё же) мысли по двум моментам…
  4. Aug 31, 2026Давайте новый тег заведём: #perf Во-первых, надо понять, что я вообще понимаю под перфом,…
  5. Aug 27, 2026#common Мы часто делаем системы, которые обладают какими-то ограничениями. Ограничения наш…
  6. Aug 24, 2026#list 0. [talk] Achieving Peak Performance for Matrix Multiplication in C++. Aliaksei Sala…
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 →