Компилятор сгенерировал рабочий конструктор по умолчанию - C++

Я пытаюсь узнать о работе конструктора по умолчанию класса и не могу разобраться в этой ситуации:

Дело 1:

class A  
{  
  public:
     int m;
     string s;
};

Затем я создаю объект этого класса:
а) A a; // Result: compiler initializing m with garbage value
б) A a = A(); // Result : compiler initializing m with garbage value

Случай 2: Теперь я удалил строку s из своего класса:

class A
{
  public:
    int m;
};

a) A a; // Result: when try to access m I get run time error
b) A a = A(); //Result: m is initialized to zero

Q1) Почему существует несоответствие в случае 1 и случае 2?
Q2) Что, если я предоставлю конструктор по умолчанию для своего класса в обоих случаях, тогда а) и б) будут одинаковыми?


person JackSparrow    schedule 19.12.2012    source источник
comment
2.a кажется странным, m должен быть неинициализирован, но не должен вызывать ошибку времени выполнения...   -  person Matteo Italia    schedule 19.12.2012
comment
Я согласен. Не знаю, почему это может привести к ошибке времени выполнения.   -  person paddy    schedule 19.12.2012
comment
@Matteo Italia: Да, это основная причина, по которой я задаю этот вопрос ... Я не знаю, почему я получаю ошибку времени выполнения.   -  person JackSparrow    schedule 19.12.2012
comment
Эта ошибка времени выполнения может быть своего рода утверждением отладки (использование неинициализированной переменной...), как то, что генерирует MSVC. Это исчезнет в релизной сборке. Конструктор по умолчанию в основном просто вызывает конструктор по умолчанию для всех членов. У int, как и у всех других примитивных типов, нет такого конструктора. И если конструктор ничего не делает, он все равно может быть оптимизирован.   -  person Sam    schedule 19.12.2012
comment
Да, это тот, который я получаю, зависит ли он от компилятора?   -  person JackSparrow    schedule 19.12.2012
comment
Да, это средства отладки MSC, включенные параметром /RTCsu (см. настройки генерации кода C/C++ в свойствах проекта). Я бы оставил это включенным, так как это помогает исправить конструкторы и инициализацию в целом.   -  person Sam    schedule 19.12.2012


Ответы (3)


Случай 1: Класс A не является POD.
Случай 2: Класс A является POD.

a) A a; //This is default initialization
b) A a = A(); // This is value initialization

Случай '1': m будет инициализирован некоторым мусорным значением конструктором по умолчанию, сгенерированным компилятором.

Случай '2': m будет инициализирован нулем, потому что A является POD.

Вы не должны получить сбой ни в одном из сценариев. Если вы это сделаете, вероятно, вы используете сломанный компилятор.

Дополнительные сведения об инициализации по умолчанию и инициализации значений см. в эта ссылка.

person Prasoon Saurav    schedule 19.12.2012

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

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

class A
{
  public:
    A::A();
    int m;
};

A::A()
  : m( 0 )
{}

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

person paddy    schedule 19.12.2012
comment
Создание объекта типа A a = A(); Гарантирует ли это, что int будет инициализирован нулем?? (Если я не дам def ctor) - person JackSparrow; 19.12.2012

Единственная разница class A между случаем 1 и случаем 2 состоит в том, что в случае 1 компилятор синтезирует нетривиальный конструктор по умолчанию, потому что s в class A не является примитивным типом. Однако в обоих случаях m не инициализируется.

person user571470    schedule 19.12.2012