Они не равны NULL, если вы не инициализируете структуру.
Snapshot s;// receives no initializationSnapshot s ={};// value initializes all members
Второй обнулит все члены, первый оставляет их с неопределенными значениями. Обратите внимание, что это рекурсивно:
structParent{Snapshot s;};Parent p;// receives no initializationParent p ={};// value initializes all members
Второе сделает p.s.{x,y}ноль. Вы не можете использовать эти агрегатные списки инициализаторов, если в вашей структуре есть конструкторы. Если это так, вам придется добавить правильную инициализацию для этих конструкторов
structSnapshot{int x;double y;Snapshot():x(0),y(0){}// other ctors / functions...};
Инициализирует и x, и y как 0. Обратите внимание, что вы можете использовать их x(), y()для инициализации независимо от их типа: это инициализация значения и обычно дает правильное начальное значение (0 для int, 0.0 для double, вызов конструктора по умолчанию для определенного пользователем типы, которые имеют объявленные пользователем конструкторы, ...). Это важно, особенно если ваша структура является шаблоном.
Это вызывает много предупреждений в моем компиляторе.
Ривер-Клэр Уильямсон
1
Роджер: Попробуйте использовать именованную структуру в инициализаторе, это то, что я делаю, и я не получаю никаких предупреждений в VC 2012: Snapshot s = Snapshot ();
Kit10
@Johannes Schaub - litb Будет ли Snapshot s = {};работать для не членов POD (для обнуления их)?
onthrocks
2
C ++ 11 теперь позволяет вам инициализировать их в определении структуры или класса, например так: struct Snapshot {double x {0}; // с фигурными скобками int y = 0; // или просто стиль старой школы 'по присваиванию', который тоже действительно инициализация};
ikku100
1
Является ли "Снимок s = {};" часть стандарта?
Стефан
41
Нет, они не равны 0 по умолчанию. Самый простой способ убедиться, что все значения или значение по умолчанию равно 0, это определить конструктор
Snapshot(): x(0), y(0){}
Это гарантирует, что все варианты использования снимка будут иметь инициализированные значения.
Недостатком является то, что структура больше не является типом POD, потому что она имеет конструктор. Это нарушит некоторые операции, такие как запись во временный файл.
finnw
16
@finnw: C ++ 11 исправляет это, хотя структура не POD, это «стандартная компоновка».
Бен Фойгт
20
В общем нет. Однако структура, объявленная как file-scope или static в функции / будет / будет инициализирована в 0 (как и все другие переменные этих областей):
int x;// 0int y =42;// 42struct{int a, b;} foo;// 0, 0void foo(){struct{int a, b;} bar;// undefinedstaticstruct{int c, d;} quux;// 0, 0}
Это действительно не безопасное предположение. Вы не должны полагаться на ценность чего-то, что вы не инициализировали
Hasturkun
24
Статические объекты продолжительности хранения всегда инициализируются нулем - цитату из стандарта см. В stackoverflow.com/questions/60653/… Хороший ли это стиль - другое дело.
bdonlan
12
С POD вы также можете написать
Snapshot s ={};
Вы не должны использовать memset в C ++, у memset есть недостаток, заключающийся в том, что если в структуре есть не POD, он уничтожит его.
или вот так:
struct init
{template<typename T>operator T *(){returnnew T();}};Snapshot* s = init();
@Andy Most Vexing Parse превращает вещи, которые выглядят как нормальные ctors - SomeType foo();это типичное, хотя это может случиться с другими - в определения функций (в этом случае, функция, fooкоторая возвращает SomeType). Извините за некро, но если кто-нибудь еще наткнется на это, подумал, что я отвечу.
Фонд Моника иск
8
В C ++ используйте конструкторы без аргументов. В C у вас не может быть конструкторов, поэтому используйте либо memsetили - интересное решение - обозначенные инициализаторы:
Я считаю, что это C, а не C ++. Он не сможет скомпилироваться под некоторыми компиляторами C ++. Я испытал сбой компиляции под Cygwin или MinGW.
jww
3
Я считаю, что правильный ответ заключается в том, что их значения не определены. Часто они инициализируются в 0 при запуске отладочных версий кода. Обычно это не тот случай, когда запускаются версии выпуска.
То же самое касается двойного; все биты ноль не обязательно 0.0. Однако вы можете проверить, есть ли у вас двойники IEEE754, и в этом случае он должен работать.
MSalters
1
Переместите элементы pod в базовый класс, чтобы сократить список инициализаторов:
Ответы:
Они не равны NULL, если вы не инициализируете структуру.
Второй обнулит все члены, первый оставляет их с неопределенными значениями. Обратите внимание, что это рекурсивно:
Второе сделает
p.s.{x,y}
ноль. Вы не можете использовать эти агрегатные списки инициализаторов, если в вашей структуре есть конструкторы. Если это так, вам придется добавить правильную инициализацию для этих конструкторовИнициализирует и x, и y как 0. Обратите внимание, что вы можете использовать их
x(), y()
для инициализации независимо от их типа: это инициализация значения и обычно дает правильное начальное значение (0 для int, 0.0 для double, вызов конструктора по умолчанию для определенного пользователем типы, которые имеют объявленные пользователем конструкторы, ...). Это важно, особенно если ваша структура является шаблоном.источник
Snapshot s = {};
работать для не членов POD (для обнуления их)?Нет, они не равны 0 по умолчанию. Самый простой способ убедиться, что все значения или значение по умолчанию равно 0, это определить конструктор
Это гарантирует, что все варианты использования снимка будут иметь инициализированные значения.
источник
В общем нет. Однако структура, объявленная как file-scope или static в функции / будет / будет инициализирована в 0 (как и все другие переменные этих областей):
источник
С POD вы также можете написать
Вы не должны использовать memset в C ++, у memset есть недостаток, заключающийся в том, что если в структуре есть не POD, он уничтожит его.
или вот так:
источник
SomeType foo();
это типичное, хотя это может случиться с другими - в определения функций (в этом случае, функция,foo
которая возвращаетSomeType
). Извините за некро, но если кто-нибудь еще наткнется на это, подумал, что я отвечу.В C ++ используйте конструкторы без аргументов. В C у вас не может быть конструкторов, поэтому используйте либо
memset
или - интересное решение - обозначенные инициализаторы:источник
Я считаю, что правильный ответ заключается в том, что их значения не определены. Часто они инициализируются в 0 при запуске отладочных версий кода. Обычно это не тот случай, когда запускаются версии выпуска.
источник
0
в тех местах памяти. Это не то же самое, что инициализация!Так как это POD (по сути, структура C), нет ничего плохого в том, чтобы инициализировать его способом C:
или аналогично
Я не пошел бы так далеко, чтобы использовать
calloc()
в программе C ++, хотя.источник
Переместите элементы pod в базовый класс, чтобы сократить список инициализаторов:
источник