Инициализация нулём
Задаёт нулевое начальное значение объекта.
Содержание |
[править] Синтаксис
Обратите внимание, что это не синтаксис инициализации нулём, для которой в языке нет специального синтаксиса. Это примеры других типов инициализации, которые могут выполнять инициализацию нулём.
static T объект ;
|
(1) | ||||||||
T () ;
T t T |
(2) | ||||||||
CharT массив [ n ] = " короткая-последовательность ";
|
(3) | ||||||||
[править] Объяснение
Инициализация нулём выполняется в следующих случаях:
Эффекты инициализация нулём:
- Если
T
является скалярным типом, объект инициализируется значением, полученным с помощью явного преобразования в типT
. - Если
T
является классовым типом не объединением:
- все биты заполнения инициализируются нулевыми битами,
- каждый нестатический элемент данных инициализируется нулями,
- каждый невиртуальный подобъект ��азового класса инициализируется нулями, и
- если объект не является подобъектом базового класса, каждый виртуальный подобъект базового класса инициализируется нулями.
- Если
T
является типом объединения:
- все биты заполнения инициализируются нулевыми битами, и
- первый нестатический именованный элемент данных объекта инициализируется нулём.
- Если
T
является типом массива, каждый элемент инициализируется нулями. - Если
T
является ссылочным типом, ничего не делается.
[править] Примечания
Как описано в нелокальной инициализации, статические и локальные в потоке (начиная с C++11) переменные, которые не инициализируются константами, инициализируются нулями до того, как произойдет любая другая инициализация. Если в определении неклассовой нелокальной переменной не указан инициализатор, то инициализация по умолчанию не делает ничего, оставляя результат предыдущей нулевой инициализации неизменённым.
Указатель, инициализированный нулём, является значением нулевого указателя своего типа, даже если значение нулевого указателя не является целочисленным нулём.
[править] Пример
#include <iostream> #include <string> struct A { int a, b, c; }; double f[3]; // инициализация нулём тремя значениями 0.0 int* p; // инициализация нулём нулевым значением указателя // (даже если значение не целочисленный 0) std::string s; // инициализация нулём неопределённым значением, затем // инициализация по умолчанию значением "" конструктором // по умолчанию std::string int main(int argc, char*[]) { delete p; // безопасно удаляется нулевой указатель static int n = argc; // инициализируется нулём значением 0, затем инициализируется // копированием argc std::cout << "n = " << n << '\n'; A a = A(); // эффект такой же как: A a{}; или A a = {}; std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n"; }
Возможный вывод:
n = 1 a = {0 0 0}
[править] Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
Номер | Применён | Поведение в стандарте | Корректное поведение |
---|---|---|---|
CWG 277 | C++98 | указатели могут быть инициализированы неконстантным выражением со значением 0, которое не является константой нулевого указателя |
должны инициализироваться целочисленным константным выражением со значением 0 |
CWG 694 | C++98 | инициализация нулём для классовых типов игнорирует заполнение |
заполнение инициализируется нулевыми битами |
CWG 903 | C++98 | инициализация нулём для скалярных типов устанавливает начальное значение в значение, преобразованное из целочисленного константного выражения со значением 0 |
объект инициализируется значением, преобразованным из целочисленного литерала 0 |
CWG 2026 | C++98 | было указано, что инициализация нулём всегда происходит первой, даже до константной инициализации |
нет инициализации нулём, если применяется константная инициализация |
CWG 2196 | C++98 | инициализация нулём для классовых типов игнорирует подобъекты базового класса |
они также инициализируются нулями |
CWG 2253 | C++98 | было неясно, применяется ли инициализация нулём к безымянным битовым полям |
применяется (все биты заполнения инициализируются нулевыми битами) |