Конструктор по умолчанию инициализирует встроенные типы?

Конструктор по умолчанию (созданный компилятором) инициализируют созданный в типах?

164
задан 3 revs, 3 users 100% 30 October 2015 в 17:15
поделиться

7 ответов

№ Конструктор по умолчанию выделяет память и вызывает конструктор без аргументов любых родителей.

-8
ответ дан 23 November 2019 в 21:14
поделиться

В соответствии со стандартом этого не произойдет, если вы явно не инициализируете в списке инициализаторов

2
ответ дан 23 November 2019 в 21:14
поделиться

Я не совсем уверен, что вы имеете в виду, но:

struct A { int x; };

int a; // a is initialized to 0
A b;   // b.x is initialized to 0

int main() {
    int c;         // c is not initialized
    int d = int(); // d is initialized to 0

    A e;           // e.x is not initialized
    A f = A();     // f.x is initialized to 0
}

В каждом случае, когда я говорю «не инициализировано» - вы можете обнаружить, что ваш компилятор дает ему согласованное значение, но стандарт этого не требует.

Много размахивания руками, в том числе и мной, о том, как встроенные типы «по сути» имеют конструктор по умолчанию. На самом деле инициализация по умолчанию и инициализация значения являются определенными терминами в стандарте, которые лично мне приходится искать каждый раз. В стандарте определены только классы, которые имеют неявный конструктор по умолчанию.

18
ответ дан 23 November 2019 в 21:14
поделиться

Технически он инициализирует их - используя конструктор по умолчанию, который, кстати, ничего не делает, кроме выделения памяти для них.

Если вы хотели бы знать, установлены ли они на что-то разумное, например, 0 для int, то ответ «нет».

-5
ответ дан 23 November 2019 в 21:14
поделиться

Для всех практических целей - нет.


Однако для реализаций, технически соответствующих стандарту C++, ответ заключается в том, что это зависит от того, является ли объект POD или нет, и от того, как вы его инициализируете. Согласно стандарту C++:

MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized

Однако в реальном мире это не очень хорошо поддерживается, поэтому не используйте это.


Соответствующие части стандарта - разделы 8.5.5 и 8.5.7

19
ответ дан 23 November 2019 в 21:14
поделиться

Неявно определенный (компилятором) конструктор класса по умолчанию не инициализирует члены встроенных типов.

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

Например, широко распространено неверное мнение, что для класса C синтаксис C() всегда вызывает конструктор по умолчанию. Однако в действительности синтаксис C() выполняет так называемую value-initialization экземпляра класса. Он будет вызывать конструктор по умолчанию, только если он объявлен пользователем. (Это в C++03. В C++98 - только если класс не является POD). Если класс не имеет объявленного пользователем конструктора, то C() не будет вызывать предоставленный компилятором конструктор по умолчанию, а выполнит особый вид инициализации, который вообще не задействует конструктор C. Вместо этого он напрямую инициализирует значение каждого члена класса. Для встроенных типов это приводит к нулевой инициализации.

Например, если у вашего класса нет объявленного пользователем конструктора

class C { 
  int x;
};

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

C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage

Тем не менее, следующие инициализации будут нулевой инициализации x, потому что они используют явный инициализатор ()

C c = C(); // Does not use default constructor for `C()` part
           // Uses value-initialization feature instead
assert(c.x == 0);

C *pc = new C(); // Does not use default constructor for `C()` part
                 // Uses value-initialization feature instead
assert(pc->x == 0);

Поведение инициализатора () в некоторых отношениях отличается между C++98 и C++03, но не в этом случае. Для приведенного выше класса C оно будет таким же: инициализатор () выполняет нулевую инициализацию C::x.

Другим примером инициализации, выполняемой без участия конструктора, является, конечно же, агрегатная инициализация

C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);

C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);
164
ответ дан 23 November 2019 в 21:14
поделиться

Как заявили предыдущие выступающие - нет, они не инициализированы.

На самом деле это источник действительно странных ошибок, поскольку современные ОС обычно заполняют только что выделенные области памяти нулями. Если вы этого ожидаете, это может сработать с первого раза. Однако по мере того, как ваше приложение продолжает работать, объекты delete -ing и new -ing, вы рано или поздно окажетесь в ситуации, когда вы ожидаете нулей, но ненулевой остаток от сидит более ранний объект.

Так почему же тогда не все новые данные размещены заново? Да, но не всегда из ОС. ОС имеет тенденцию работать с большими кусками памяти (например, 4 МБ за раз), поэтому все крошечные выделения и освобождение одного слова здесь, три байта, там, обрабатываются в uyserspace и, следовательно, не обнуляются.

PS. Я написал "склонен", т.е. с первого раза нельзя даже рассчитывать на успех ...

1
ответ дан 23 November 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: