Подтвердить что ты не робот

Конструктор С++ имеет конструктор по умолчанию?

Я написал следующий фрагмент кода:

void foo()
{
    struct _bar_ 
    {
        int a;
    } bar; 

    cout << "Value of a is " << bar.a;
}

и скомпилировал его с помощью g++ 4.2.1 (Mac). Вывод: "Значение a равно 0".

Можно ли сказать, что элементы данных структуры в С++ всегда инициализируются по умолчанию (по сравнению с c)? Или наблюдаемый результат просто совпадение?

Я могу себе представить, что структуры в С++ имеют конструктор по умолчанию (поскольку структура и класс почти одинаковы в С++), что объясняет, почему элемент данных a из строки инициализируется равным нулю.

4b9b3361

Ответ 1

Простой ответ - да. Он имеет конструктор по умолчанию.

Примечание: структура и класс идентичны (кроме состояния по умолчанию для спецификаторов доступа).

Но независимо от того, будет ли он инициализироваться, члены будут зависеть от того, как объявляется фактический объект. В вашем примере элемент не инициализирован, а a имеет неопределенное значение.

void func()
{
    _bar_  a;                 // Members are NOT initialized.
    _bar_  b = _bar_();       // Members are zero-initialized
    // From C++14
    _bar_  c{};               // New Brace initializer (Members are zero-initialized)


    _bar_* aP = new _bar_;    // Members are NOT initialized.
    _bar_* bP = new _bar_();  // Members are zero-initialized
    // From C++14
    _bar_  cP = new _bar_{};  // New Brace initializer (Members are zero-initialized)
}

// static storage duration objects
//   i.e. objects at the global scope.
_bar_ c; // Members are zero-initialized.

Точные подробности объясняются в стандарте в пунктах 8.5 Initializers [dcl.init] абзацев 4-10. Но следующее упрощенное резюме для этой ситуации.

Структура без определенного пользователем конструктора имеет сгенерированный компилятором конструктор. Но то, что оно делает, зависит от того, как оно используется, и оно будет либо инициализировать по умолчанию свои члены (что для типов POD обычно не имеет значения), либо может инициализировать его члены нолем (что для POD обычно означает, что его члены равны нулю).

PS. Не используйте _ как первый символ в имени типа. Вы столкнетесь с проблемами.

Ответ 2

Можно ли сказать, что элементы данных структуры в С++ всегда инициализируются по умолчанию (по сравнению с c)? Или наблюдаемый результат просто совпадение?

Это совпадение.

Ваш код вызывает Undefined Поведение; если вы явно не установите члены в 0, они могут быть чем угодно.

Ответ 3

Не ответ, но вы можете принять это... если вы хотите попробовать:

void foo() {
   struct test {
      int value;
   } x;
   std::cout << x.value << std::endl;
   x.value = 1000;
}
int main() {
   foo();
   foo();
}

В вашем примере память уже имела значение 0 до того, как была создана переменная, поэтому вы можете назвать это удачным совпадением (на самом деле, некоторые ОС будут обнулять всю память перед началом процесса, а это значит, что 0 это довольно вероятное значение для поиска в небольшой короткой программе...), предыдущий код будет вызывать функцию дважды, а память с первого вызова будет повторно использоваться во втором, скорее всего, второй раз вокруг него будет print 1000. Обратите внимание, однако, что значение по-прежнему undefined, и что этот тест может показывать или не показывать ожидаемый результат (т.е. есть много вещей, которые может сделать компилятор и генерирует другой результат...)

Ответ 4

Элементы-члены структуры не инициализируются по умолчанию. Точно так же, как класс (потому что структура - это точно то же самое, что и класс, только в структуре члены являются общедоступными по умолчанию).

Ответ 5

Не полагайтесь на эту функциональность, она нестандартная

просто добавьте

foo() : a() {}

Я не могу вспомнить точное состояние gcc 4.2 (я думаю, что он слишком старый), но если вы используете С++ 11, вы можете сделать следующее

foo()=default;