Инициализированный по умолчанию против Инициализированного значения - PullRequest
5 голосов
/ 20 ноября 2011

Из этого ответа , в C ++ 03 тип POD инициализируется по умолчанию, если () опущено, в противном случае он инициализируется значением.

// POD type
struct foo {
     int x;
};

// value-initialized
new foo();

Но еслиПредоставляется определяемый пользователем конструктор. Будет ли какой-либо из объектов, представленных ниже, считаться установленным по умолчанию или инициализированным значением?

// non-POD type
struct bar {
     bar(int x = 0):x(x) {}
     int x;
};

new bar();
new bar(42);

Ответы [ 2 ]

3 голосов
/ 21 ноября 2011

В C ++ 03 тип POD инициализируется по умолчанию, если () опущен, в противном случае он инициализируется значением.

Это не совсем то, что происходит.Согласно спецификации C ++ 03, раздел 8.5 / 9, если для нестатического объекта типа POD не указан инициализатор, то он и его подобъекты «имеют неопределенное начальное значение».То есть не то же самое, что и инициализация по умолчанию.Инициализация по умолчанию - это то же самое, что и инициализация значения для POD-типа, что означает, что объект инициализируется нулями (8.5 / 5), но это может произойти только при наличии пустого инициализатора (то есть пустых скобок).согласно 8.5 / 7).Таким образом, вы можете только по умолчанию и / или инициализировать значение POD-типа с пустым инициализатором.Инициализация по умолчанию для нестатического POD-типа не происходит, если не указан инициализатор.

Во втором примере с не-POD-типом, который имеет определяемый пользователем конструктор, по умолчанию инициализация по умолчанию будет выполняться технически.поместите, если вы пропустили символы-инициализаторы (круглые скобки).Другими словами:

bar* ptr_a = new bar; //default initialization
bar* ptr_b = new bar(); //value initialization

Имейте в виду, что для структур, не относящихся к POD, или для типов классов, если есть определяемый пользователем конструктор, инициализация по умолчанию и инициализация значения, согласно 8.5 / 5,оба вызывают определяемый пользователем конструктор.Таким образом, в конце концов, с типом bar в том виде, в каком вы его объявили, инициализация по умолчанию и значение заканчивают тем же.

2 голосов
/ 21 ноября 2011

Если ваш класс имеет определяемый пользователем конструктор по умолчанию, то и инициализация по умолчанию, и инициализация значения приводят к вызову этого конструктора. Все, что происходит дальше, зависит от конструктора:

struct UDT
{
  int a;
  int b;
  Foo c;
  Foo d;
  UDT() : a(), c() {}
};

Инициализация по умолчанию и инициализация значения объекта класса UDT приведут к инициализации значения UDT::a и UDT::c (поэтому a равно нулю), потому что в списке инициализатора так сказано, а UDT::b и UDT::d сами инициализируются по умолчанию (поэтому b неинициализирован, а для d применяется та же логика рекурсивно).

Подробнее об инициализации см. 8.5, а о списках инициализаторов - 12.6.2 (особенно пункт 8).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...