Использование std :: map в качестве ассоциативного массива - PullRequest
1 голос
/ 09 октября 2009

Итак, я использую std :: map в качестве ассоциативного массива. Карта объявлена ​​таковой:

std::map<int, CustomClass*> CustomContainer;

Позже я использую объект CustomContainer в качестве ассоциативного массива, например,

CustomClass* pClass = CustomContainer[ID]

Йосуттис заявляет:

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

Значение карты имеет тип CustomClass *. Будет ли значение по умолчанию NULL или оно не определено? (Я думаю, что это не так, поскольку указатель не является фундаментальным типом данных). Я думаю, что это также будет зависеть от конструктора и от его поведения ... мысли ???

Единственный конструктор CustomClass выглядит так:

CustomClass::CustomClass(ClassA param1, ClassB param2, ClassC param3, ClassD param4)
:privateClassA(param1),
privateClassB(param2),
privateClassC(param3),
privateClassD(param4)
{

}

Большое спасибо!

Ответы [ 4 ]

13 голосов
/ 09 октября 2009

Неинициализированная локальная переменная или поле указателя будет иметь неопределенное значение, как неинициализированная int (или, как правило, POD-тип) локальная переменная или поле. Однако это не имеет ничего общего с вопросом.

Когда вы используете operator[] на карте и она создает новую запись, она инициализируется по умолчанию . Это означает нулевое значение указателя для указателей (и 0 для int s и т. Д.). Это никогда не будет неопределенным.

Если вам действительно нужно проверить, есть ли элемент с таким ключом на карте или нет, и не хотите новых записей, используйте функцию find() member и сравните возвращенный итератор с end().

9 голосов
/ 09 октября 2009

Вместо этого используйте map :: find и полностью избежите проблемы.

std::map<int, CustomClass*>::iterator i = CustomContainer.find(ID);
if (i != CustomContainer.end())
{
    CustomClass* pClass = i->second;
    ...
4 голосов
/ 09 октября 2009
0 голосов
/ 09 октября 2009

Ваша карта содержит CustomClass *, поэтому при вызове CustomContainer [newID] создается указатель, а не экземпляр CustomClass. Значение указателя будет неопределенным - даже если вам повезет, и изначально оно равно NULL, вам не следует рассчитывать на это поведение. Да, я не прав насчет последней части.

Проверить наличие идентификатора на карте можно следующим образом:

(CustomContainer.find(someID) == map<int,CustomClass>::end)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...