Странное поведение конструктора по умолчанию в классе, унаследованном от структуры POD - PullRequest
2 голосов
/ 26 сентября 2011

Этот вопрос относится к этому .

Как я упоминал в предыдущем вопросе, я решил унаследовать свой класс от структуры Win BITMAP, чтобы обеспечить некоторые расширенные функциональные возможности.

Я заметил интересную деталь в поведении скомпилированной программы. Сначала я определил конструктор по умолчанию для своего класса, как показано ниже:

CPreviewFrame::CPreviewFrame():
   m_bufferSize( 0 )
{
   bmBits = NULL; //ensure that compiler in debug won't init it with 0xccccc... and delete[] will do the job
}

По идее компилятор должен был генерировать код, который вызывает конструктор по умолчанию для базового типа, даже если он не вызывался вручную в списке инициализации. Но во время отладки я заметил, что элементы данных BITMAP не инициализируются! Я добавил ручную инициализацию для BITMAP, и она работала - все элементы данных были инициализированы нулями:

CPreviewFrame::CPreviewFrame():
   BITMAP( ),
   m_bufferSize( 0 )
{
   //bmBits = NULL; //it's not needed anymore probably
}

Почему это происходит? Разве компилятор не обязан вызывать конструктор по умолчанию или он применяется только к классам? (я так не думаю - единственная разница в квалификаторах доступа по умолчанию для членов и для наследования)

1 Ответ

4 голосов
/ 26 сентября 2011

Если вы не предоставите явный инициализатор для POD-структуры, тогда объект имеет неопределенное начальное значение в соответствии с разделом 8.5 / 9 стандарта C ++.Добавление инициализатора для BITMAP, который является пустым набором скобок, в список инициализаторов вашего значения конструктора CPreviewFrame инициализирует объект BITMAP согласно Разделу 8.5 / 7.В соответствии с разделом 8.5 / 5 это будет означать, что все нестатические члены BITMAP будут инициализироваться нулями, поскольку они не являются массивами, объединениями или типами классов.

В исходном примере, однако,Вы только инициализировали элемент bmBits структуры BITMAP в фактическом теле конструктора CPreviewFrame ..., который оставляет остальные элементы данных BITMAP неопределенными значениями, так как инициализатор не был указандля самой структуры BITMAP.Поскольку каждый нестатический элемент данных класса инициализируется до вызова фактического тела конструктора, отсутствие явного инициализатора для BITMAP, который является нестатическим элементом данных POD-структуры вашего CPreviewFrame class означает, что поведение, описанное в 8.5 / 9, где значения установлены в неопределенное начальное значение, вступает в силу.

...