Модуль: Присваивание и инициализация переменных


10. 4*. Инициализации списком


Современный способ инициализации объектов в C++ - это форма инициализации, использующая фигурные скобки. Это называется инициализация списком (или равномерной инициализацией, или инициализацией скобками).

Списочная инициализация бывает трех видов:

int width{5};       // прямая инициализация списком значения 5 в переменную width (предпочтительно)
int height = {6};   // копирующая инициализация списком значения 6 в переменную height
int depth {};       // инициализация значений
 

До появления списочной инициализации некоторые типы инициализации требовали использования инициализации копированием, а другие - прямой инициализации. Инициализация списков была введена для обеспечения более последовательного синтаксиса инициализации (поэтому ее иногда называют "унифицированной инициализацией"), который работает в большинстве случаев.

 
Инициализация списком запрещает сужающие преобразования

Основное преимущество списочной инициализации заключается в том, что "сужающие преобразования" запрещены. Это означает, что если вы попытаетесь инициализировать переменную списком, используя значение, которое переменная не может безопасно хранить, компилятор должен выдать диагностику (обычно ошибку). Например:

int main()
{
    // Целое число может содержать только недробимые значения
    int w1 { 4.5 }; // Ошибка компиляции: Инициализация списком не позволяет сузить преобразование 4.5 в 4

    int w2 = 4.5;   // компилируется: инициализация копированием инициализирует w2 значением 4
    int w3(4.5);    // компилируется: прямая инициализация инициализирует w3 значением 4

    return 0;
}


В строке 4 приведенной выше программы мы используем значение (4.5) с дробной составляющей (.5) для списочной инициализации целочисленной переменной (которая может хранить только нефракционные значения). Поскольку это сужающее преобразование, компилятор должен выдавать ошибку в таких случаях.

Инициализация копированием (строка 6) и прямая инициализация (строка 7) оба просто отбрасывают .5 и инициализируют переменную значением 4 (что, вероятно, не то, что нам нужно). Ваш компилятор может предупредить вас об этом, поскольку потеря данных редко бывает желательной, но может и не предупредить.

Инициализация списков является предпочтительной формой инициализации в современном C++

Подводя итог, можно сказать, что инициализация списка в целом предпочтительнее других форм инициализации, поскольку она работает в большинстве случаев (и поэтому наиболее последовательна), не допускает сужающих преобразований (которые нам обычно не нужны) и поддерживает инициализацию списков значений (о чем мы расскажем в одном из следующих уроков). Пока вы учитесь, мы рекомендуем придерживаться прямой инициализации списков (и инициализации значений).

time 1000 ms
memory 256 Mb

Комментарий учителя