tags:

views:

277

answers:

4

So, I'm using a std::map as an associative array. The map is declared as such:

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

Later on, I use the CustomContainer object as an associative array, e.g.,

CustomClass* pClass = CustomContainer[ID]

Josuttis states:

If you use a key as the index, for which no element yet exists, a new element get inserted into the map automatically. The value of the new element is initialized by the default constructor of its type. Thus, to use this feature you can't use a value type that has no default constructor

The value of the map is of type CustomClass*. Will the value default to NULL, or is it undefined? (I think that it wouldn't, as "pointer" isn't a fundamental data type). I would think it would also rely somewhat on the constructor and the behavior there as well.... thoughts???

The only constructor of CustomClass looks like this:

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

}

Thanks much!

+8  A: 

Use map::find instead and avoid the problem entirely.

std::map<int, CustomClass*>::iterator i = CustomContainer.find(ID);
if (i != CustomContainer.end())
{
    CustomClass* pClass = i->second;
    ...
Mark Ransom
Actually, the last line in this code is not correct. For what I'm trying to do, it would be CustomClass* pClass = i->second;
jdt141
Of course. Thanks for the heads up, I've corrected it. I keep forgetting that the iterator for std::map returns a pair; luckily the compiler tells me every time I make that mistake.
Mark Ransom
A: 

Your map is holding CustomClass*, so a call to CustomContainer[newID] constructs a pointer, not an instance of CustomClass. The value of the pointer is going to be undefined - even if you get lucky and it is NULL initially you shouldn't really count on that behavior.

Yeah I'm wrong about that last part.

You can test for the existence of an ID in the map this way:

(CustomContainer.find(someID) == map<int,CustomClass>::end)
daveg
-1, simpy wrong. See what "default initialization" means in C++ spec.
Pavel Minaev
+4  A: 

It will be a NULL pointer: what-is-the-default-constructor-for-c-pointer

Keith Randall
+10  A: 

An uninitialized local pointer variable or field will have undefined value, just like uninitialized int (or, in general, POD-type) local variable or field would. However, this has nothing to do with question at hand.

When you use operator[] on map, and it creates a new entry, it is default-initialized. This means null pointer value for pointers (and 0 for ints, and so on). It would never be undefined.

If you actually need to check if there is an item with such key in the map or not, and do not want new entries, use find() member function, and compare the returned iterator to end().

Pavel Minaev
"An uninitialized local pointer variable or field will have undefined value" is not true, see other answer from Keith Randall.
Thomas
Hi Pavel - thanks much. You answered my question exactly. My current reference doesn't mention anything about objects being "default initialized". Could you point me to something? Thanks again!
jdt141
@Thomas: If something is uninitialized, what value do you expect it to have? You can't expect any value, uninitialized data is undefined in value.
GMan
Keith's answer explains what a value of a default-initialized pointer will be. A local variable of pointer type without an initializer will not be default-initialized.
Pavel Minaev
@jdt: the primary reference for this is ISO C++ standard. It defines `operator[](x)` as equivalent to: `(*((insert(make_pair(x, T()))).first)).second`. The part that does default initialization here is `T()`, which creates a default-initialized temporary of type `T`. If `T` is a pointer type, this will be a null pointer.
Pavel Minaev