инициализация массива - PullRequest
       15

инициализация массива

0 голосов
/ 27 октября 2009

Я вполне уверен, что массивы встроенных типов унифицированы, тогда как массивы UDT инициализируются по умолчанию.

int foo[5]; // will contain junk <br> Foo foo[5]; // will contain 5 Foo objects that are default initialized

Это происходит независимо от того, выделен ли массив в стеке или в куче.

Однако мне трудно найти авторитетный источник по этому вопросу. Бьярне утверждает, что:

«Члены массивов и структур инициализируются по умолчанию или нет в зависимости от того, является ли массив или структура статическим», что на самом деле не говорит мне слишком много.

Я также пытался найти что-то в стандарте, но пока безрезультатно.

Кто-нибудь знает авторитетный источник, подтверждающий вышесказанное?

Ответы [ 3 ]

7 голосов
/ 27 октября 2009

ISO C ++ 03 настолько авторитетен, насколько это возможно:

POD-структура - это агрегатный класс, который не имеет нестатических членов-данных типа non-POD-struct, non-POD-union (или массива таких типов) или ссылки, и не имеет пользовательского назначения копирования оператор и нет пользовательского деструктора. Аналогично, POD-объединение - это совокупное объединение, которое не имеет нестатических членов-данных типа non-POD-struct, non-POD-union (или массива таких типов) или ссылки, и не имеет пользовательского оператора назначения копирования и нет пользовательского деструктора. POD-класс - это класс, который является POD-структурой или POD-объединением.

Арифметические типы (3.9.1), типы перечисления, типы указателей и указатели на типы элементов (3.9.2) и cv-квалифицированные версии этих типов (3.9.3) вместе называются скалярными типами. Скалярные типы, типы POD-структур, типы POD-объединения (раздел 9), массивы таких типов и cv-квалифицированные версии этих типов (3.9.3) вместе называются типами POD.

Инициализация объекта типа T с нуля означает:

  • если T - скалярный тип (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;
  • если T является типом класса, не являющимся объединением, каждый нестатический член данных и каждый базовый класс подобъект инициализируется нулями;
  • если T является типом объединения, первый именованный элемент данных объекта инициализируется нулями;
  • если T является типом массива, каждый элемент инициализируется нулями;
  • если T является ссылочным типом, инициализация не выполняется.

Инициализация по умолчанию объекта типа T означает:

  • если T является типом класса, отличным от POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
  • если T является типом массива, каждый элемент инициализируется по умолчанию;
  • в противном случае объект инициализируется нулями.

Инициализация значения объекта типа T означает:

  • если T является типом класса (раздел 9) с объявленным пользователем конструктором (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
  • если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса в T инициализируется значением;
  • если T является типом массива, то каждый элемент инициализируется значением;
  • в противном случае объект инициализируется нулями

Каждый объект статической длительности хранения должен быть инициализирован нулем при запуске программы перед любой другой инициализацией. [Примечание: в некоторых случаях дополнительная инициализация выполняется позже.]

Объект, инициализатором которого является пустой набор скобок, т. Е. (), Должен быть инициализирован значением.

Если для объекта не указан инициализатор, и объект относится к (возможно, cv-квалифицированному) не относящемуся к POD типу класса (или его массиву), объект должен инициализироваться по умолчанию; если объект имеет константный тип, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение); если объект или какой-либо из его подобъектов имеют константный тип, программа некорректна.

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

Статические переменные и поля во всех случаях будут инициализироваться нулями. Обратите внимание, что это также относится и к не POD - это означает, что статическая переменная типа класса гарантированно рекурсивно установит для всех полей значение (T)0 даже до запуска ее конструктора.

Удобный прием для инициализации по умолчанию любого агрегатного типа POD заключается в использовании {} в инициализаторе - обратите внимание, что он работает как со структурами, так и с массивами:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized
1 голос
/ 27 октября 2009

В стандарте C ++ написано в 8.5.9:

Если инициализатор не указан для объект, и объект имеет (возможно cv-квалифицированный) не класс POD (или его массив), объект должен быть по умолчанию инициализируется; если объект константного типа, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если инициализатор не указанный для нестатического объекта, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение.

1 голос
/ 27 октября 2009

"Члены массивов и структур инициализируются по умолчанию или нет в зависимости от того, является ли массив или структура статическим"

Это авторитетно, хотя может быть и понятнее:

  • Массивы и структуры, объявленные как static, инициализируются нулями.
  • Локальные массивы и структуры встроенных типов (, т.е. типы, не имеющие конструкторов) не инициализируются.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...