c ++ 03: конструктор по умолчанию для встроенных типов в std :: map - PullRequest
5 голосов
/ 28 февраля 2012

Я всегда думал, что следующий код

std::map<int, int> test;
std::cout << test[0] << std::endl;

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

Вопрос в том, когда инициализация нуля выполняется для стандартных типов (int / char / float / double / size_t)? Я вполне уверен, что если я объявлю int i; в середине нигде, он будет содержать случайные данные.

P.S. Вопрос о стандарте C ++ 03. Причина этого вопроса в том, что теперь я больше не уверен, когда у меня есть для обеспечения инициализации для встроенных типов, таких как int / float / size_t, или когда его можно безопасно опустить.

Ответы [ 5 ]

9 голосов
/ 28 февраля 2012

Стандартные контейнеры (map, vector и т. Д.) Всегда будут инициализировать значение их элементы.

Грубо говоря, инициализация значения is:

  • инициализация по умолчанию при наличии конструктора по умолчанию
  • инициализация с нуля в противном случае

(Кто-то скажет, лучшее из обоих миров)

Синтаксис прост: T t = T(); будет инициализировать значение tT t{}; в C ++ 11).

Когда вы используете map<K,V>::operator[], часть «значение» пары инициализируется значением, что для встроенного типа дает 0.

1 голос
/ 28 февраля 2012

В частности, для вышеуказанного случая:

std::map<int, int> test;
std::cout << test[0] << std::endl;

Мы используем std::map::operator[];

Ссылаясь http://www.cplusplus.com/reference/stl/map/operator[]/

Для T & map :: operator [] (const key_type & x);

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

Итак, test[0] приводит к test[0] = int();

Живой пример здесь: http://ideone.com/8yYSk

Также читайте: std :: map значение по умолчанию для встроенного типа

1 голос
/ 28 февраля 2012

Я почти уверен, что если я объявлю int i;в середине нигде он будет содержать случайные данные.

Нет, не всегда.

Если вы создадите объект типа POD, он будет унифицирован:

struct A
{
  int iv;
  float fv;
};

int main()
{
  A a; // here the iv and fv are uninitialized
}

Как только вы добавляете конструктор, они инициализируются:

struct A
{
  A(){} // iv and fv initialized to their default values
  int iv;
  float fv;
};

int main()
{
  A a; // here the iv and fv are initialized to their default values
}
0 голосов
/ 28 февраля 2012

обратите внимание, что типы данных, такие как char, int, float, не инициализируются.но вместо этого в данном конкретном случае он был инициализирован, потому что он использовался в классе контейнера stl.

Все объекты класса контейнера stl инициализируются.

0 голосов
/ 28 февраля 2012

Самое простое решение - просто создать оболочку шаблона, которая всегда будет инициализироваться.

...