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

У меня есть struct:

   struct Snapshot
    {
        double x; 
        int   y ;

    };

Я хочу, чтобы x и y равнялись 0. По умолчанию они будут 0 или мне нужно делать:

Snapshot s= {0,0};

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

Ответ 1

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

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, call конструктор по умолчанию для пользовательских типов, которые имеют объявленные конструкторы,...). Это важно, особенно если ваша структура является шаблоном.

Ответ 2

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

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

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

Ответ 3

В общем, нет. Однако структура, объявленная как область файла или статическая в функции/будет/инициализирована до 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
}

Ответ 4

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

Snapshot s = {};

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

или вот так:

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

Snapshot* s = init();

Ответ 5

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

struct Snapshot s = { .x = 0.0, .y = 0.0 };

Ответ 6

Поскольку это POD (по существу, C-структура), нет никакого вреда в инициализации этого пути C:

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

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

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

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

Ответ 7

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

Ответ 8

Переместите элементы 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());
}