Являются ли члены структуры C ++ инициализированы в 0 по умолчанию?

у меня есть этоstruct:

struct Snapshot
{
    double x; 
    int y;
};

я хочуx а такжеy быть 0. Будут ли они по умолчанию 0 или я должен сделать:

Snapshot s = {0,0};

Каковы другие способы обнуления структуры?

 Shafik Yaghmour25 февр. 2019 г., 12:04
 Jonny05 апр. 2016 г., 09:12
Используйте std :: map & lt; & gt; и вернуть 0, когда ключ не существует.

Ответы на вопрос(8)

В C ++ используйте конструкторы без аргументов. В C вы не можете иметь конструкторов, поэтому используйте либоmemset или - интересное решение - обозначенные инициализаторы:

struct Snapshot s = { .x = 0.0, .y = 0.0 };
 12 авг. 2015 г., 09:50
Я считаю, что это C, а не C ++. Он не сможет скомпилироваться под некоторыми компиляторами C ++. Я испытал сбой компиляции под Cygwin или MinGW.
Решение Вопроса

Они не равны нулю, если вы не инициализируете структуру.

Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members

Второй обнулит все элементы, первый оставляет их с неопределенными значениями. Обратите внимание, что это рекурсивно:

struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members

Второе сделаюp.s.{x,y} нуль. Вы не можете использовать эти агрегатные списки инициализаторов, если у вас есть конструкторы в вашей структуре. Если это так, вам придется добавить правильную инициализацию для этих конструкторов

struct Snapshot {
    int x;
    double y;
    Snapshot():x(0),y(0) { }
    // other ctors / functions...
};

Инициализирует и x, и y как 0. Обратите внимание, что вы можете использоватьx(), y() чтобы инициализировать их, не обращая внимания на их тип: это затем инициализирует значение и обычно дает правильное начальное значение (0 для int, 0,0 для double, вызов конструктора по умолчанию для пользовательских типов, которые имеют конструкторы, объявленные пользователем, ...). Это важно, особенно если ваша структура является шаблоном.

 17 июл. 2018 г., 15:42
Is & quot; Снимок s = {}; & quot; часть стандарта?
 19 авг. 2013 г., 16:10
Роджер: Попробуйте использовать именованную структуру в инициализаторе, это то, что я делаю, и я не получаю никаких предупреждений в VC 2012: Snapshot s = Snapshot ();
 05 мая 2016 г., 19:36
C ++ 11 теперь позволяет вам инициализировать их в определении структуры или класса, например так: struct Snapshot {double x {0}; // с фигурными скобками int y = 0; // или просто стиль старой школы "по назначению" что на самом деле тоже инициализация};
 22 мар. 2013 г., 19:26
Это производит много предупреждений в моем компиляторе.
 15 окт. 2013 г., 11:58
@ Йоханнес Шауб - Литл УиллSnapshot s = {}; работать для не членов POD (для обнуления их)?

Переместите члены модуля в базовый класс, чтобы сократить список инициализаторов:

struct foo_pod
{
    int x;
    int y;
    int z;
};

struct foo : foo_pod
{
    std::string name;
    foo(std::string name)
        : foo_pod()
        , name(name)
    {
    }
};

int main()
{
    foo f("bar");
    printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}

Я считаю, что правильный ответ заключается в том, что их значения не определены. Часто они инициализируются равными 0 при запуске отладочных версий кода. Обычно это не тот случай, когда запускаются версии выпуска.

 17 янв. 2012 г., 17:04
На самом деле, отладочные версии уже имеют0 в тех местах в памяти. Это не то же самое, что инициализация!

В общем нет. Однако структура, объявленная как file-scope или static в функции / будет / будет инициализирована в 0 (как и все другие переменные этих областей):

int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0

void foo() {
  struct { int a, b; } bar; // undefined
  static struct { int c, d; } quux; // 0, 0
}
 01 июл. 2009 г., 18:02
Это действительно не безопасное предположение. Вы не должны полагаться на ценность того, что не инициализировали
 01 июл. 2009 г., 18:13
Статические объекты продолжительности хранения всегда инициализируются нулем - см.stackoverflow.com/questions/60653/… для цитаты из стандарта. Хороший ли это стиль - другое дело.

Так как это POD (по сути, структура C), нет ничего плохого в том, чтобы инициализировать его способом C:

Snapshot s;
memset(&s, 0, sizeof (s));

или аналогично

Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));

Я бы не пошел так далеко, чтобы использоватьcalloc() в программе на C ++.

 01 июл. 2009 г., 17:28
Он не переносимый. Указатель 0 может иметь значение, отличное от 0.
 01 июл. 2009 г., 18:04
@ Сергей, да, но эта структура не содержит указателей.
 02 июл. 2009 г., 10:54
То же самое касается двойного; ноль все биты не обязательно равен 0,0. Тем не менее, вы можете проверить, есть ли у вас двойники IEEE754, и в этом случае он должен работать.

Нет, они не равны 0 по умолчанию. Самый простой способ убедиться, что все значения или значение по умолчанию равно 0, это определить конструктор

Snapshot() : x(0), y(0) {
}

Это гарантирует, что все варианты использования снимка будут иметь инициализированные значения.

 01 июл. 2009 г., 17:12
Недостатком является то, что структура больше не является типом POD, потому что она имеет конструктор. Это нарушит некоторые операции, такие как запись во временный файл.
 05 авг. 2012 г., 01:08
@finnw: C ++ 11 исправляет это, хотя структура не POD, это «стандартная компоновка».

С POD вы также можете написать

Snapshot s = {};

Вы не должны использовать memset в C ++, у memset есть недостаток, заключающийся в том, что если в структуре есть не-POD, он уничтожит его.

или вот так:

struct init
{
  template <typename T>
  operator T * ()
  {
    return new T();
  }
};

Snapshot* s = init();
 06 нояб. 2017 г., 10:19
@QPaysTaxes thx
 17 янв. 2012 г., 16:58
 03 нояб. 2017 г., 23:53
@ Andy Most Vexing Parse превращает вещи, которые выглядят как обычные ctors -SomeType foo(); является типичным, хотя это может случиться с другими - в определениях функций (в этом случае функцияfoo это возвращаетSomeType). Извините за некро, но если кто-то еще наткнется на это, решил, что я отвечу.

Ваш ответ на вопрос