Путаница в понимании стандартов C ++ - PullRequest
11 голосов
/ 08 декабря 2010

В C ++ 98

12.6.2 / 4 : после завершения вызова конструктора для класса X, если член X не указан в конструктор * mem-initializers , не инициализированный по умолчанию, и не инициализированный во время выполнения тела конструктора , член имеет неопределенное значение.

Что не инициализируется во время выполнения тела конструктора ?Может ли элемент быть инициализированным внутри тела конструктора?

Ответы [ 2 ]

11 голосов
/ 08 декабря 2010

ни инициализированы во время выполнения тела конструктора неверно ИМХО.

Формулировки были изменены в C ++ 03 с , ни инициализированы (в C ++ 98) до и не задано значение

После завершения вызова конструктора для класса X, если член X не указан в записке конструктора-инициализаторы, ни инициализированные по умолчанию, ни инициализированные значением, , ни заданные значения во время выполнения тела конструктора, член имеет неопределенное значение.

3 голосов
/ 08 декабря 2010

Это на самом деле очень просто. Члены класса / структуры могут включать объекты с конструкторами по умолчанию, но если они этого не делают, и вы не удосуживаетесь дать им значение в списке инициализатора, ни установить их в теле конструктора, то в основном память, которую они Занимайте - все, что было найдено для них из стека или кучи - все равно будет содержать старый мусор, то есть неопределенное значение.

Рассмотрим:

struct X
{
    X() : x1(1) { x2 = 2; }
    double x1, x2, x3;
    std::string x4;
};

Здесь x1 и x2 явно инициализируются конструктором X, а x4 - будучи std::string - по умолчанию составляется как "" / length 0. x3, однако , может быть чем угодно - и его не следует читать до тех пор, пока он не будет установлен (это неопределенное поведение и действительно может кусаться в некоторых системах), учитывая, что битовый массив памяти, который он занимает, может даже не быть допустимым значением для двойного поэтому чтение из него может вызвать некоторое исключение процессора / прерывание / прерывание).

...