Пространства имён
Варианты
Действия

Инициализация нулём

Материал из cppreference.com
< cpp‎ | language

Задаёт нулевое начальное значение объекта

Содержание

[править] Syntax

static T object ; (1)
T () ;

T t = {} ;
T {} ;

(2)

(начиная с C++11)
CharT array [ n ] = ""; (3)

[править] Объяснение

Инициализация-нулём выполняется в следующих случаях:

1) Для каждой именованной переменной со статическим или потоковым классом памяти не подлежащей инициализации константой (начиная с C++14) до любой другой инициализации.
2) Как часть процедуры инициализации-значением для неклассовых типов и для членов, инициализированных значением классовых типов, не имеющих конструкторов, включая инициализацию значением элементов агрегатов, для которых не заданы инициализаторы.
3) Если массив любого символьного типа инициализирован строковым литералом меньшего размера, то оставшиеся элементы массива инициализируются нулём.

Эффекты инициализация нулём:

  • Если T является скалярным типом, начальным значением объекта будет целочисленная нулевая константа явно преобразованная к типу T.
  • Если T является классовым типом и не является объединением, то все базовые классы, нестатические данные-члены, а также все незаполненные байты инициализируются нулём. Наличие конструкторов игнорируется.
  • Если T является типом объединения, то первый нестатический именованный член-данное и все байты выравнивания инициализируются нулём.
  • Если T является массивом, то каждый элемент инициализируется нулём.
  • Если T является ссылкой, то инициализация не производится.

[править] Примечания

Как описано в инициализация нелокальных переменных, переменные со статическим и потоковым классом памяти не инициализированные константой (начиная с C++14) инициализируются нулём до любой другой инициализации. Если в определении неклассовой нелокальной переменной не указан инициализатор, то инициализация-по-умолчанию не делает ничего, оставляя неизменённым результат ранее проведённой инициализации-нулём.

Инициализированный нулём указатель является нулевым указательным значением соответсвтвующего типа, даже если значение нулевого указателя - не целочисленный ноль.

[править] Пример

#include <string>
#include <iostream>
 
struct A {
    int a,b,c;
};
 
double f[3]; // инициализация-нулём тремя значениями 0.0
int* p;   // инициализация-нулём нулевым указательным значением
std::string s; // инициализация-нулём неопределённым значением
               // затем инициализация-по-умолчанию значением ""
int main(int argc, char* argv[])
{
    A a = A();
    std::cout << a.a << a.b << a.c << '\n';
    static int n = argc; // инициализация-нулём значением 0
                         // затем инициализация-копированием значением argc
    delete p; // можно безопасно удалять нулевой указатель
}

Вывод:

000

[править] Дефекты стандарта

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
CWG 2026 C++14 zero-init was specified to always occur first, even before constant-init no zero-init if constant init applies

[править] См. также