I want to inherit from std::map
, but as far as I know std::map
hasn\'t any virtual destructor.
Is it therefore possible to call std
@Matthieu M you said
I want to inherit from std::map [...]
Why ?
There are two traditional reasons to inherit:
- to reuse its interface (and thus, methods coded against it)
- to reuse its behavior
The former makes no sense here as map does not have any virtual method so you cannot modify its behavior by inheriting; and the latter is a perversion of the use of inheritance which only complicates maintenance in the end.
Regarding "the former":
The clear()
function is virtual, and to me it makes a lot of sense for a std::map
to be overridden in a derived class with an iterator that deletes all the pointed to instances of the value class before calling the base class clear()
to prevent accidental memory leaks, and it's a trick that I've actually used. As for why someone would want to use a map to pointers to classes, well polymorphism and references not being re-assignable means that the can't be used in a STL container. You might instead suggest the use of a reference_wrapper or smart pointer such as a shared_ptr
(C++11 features) but when you're writing a library that you want somebody restricted to a C++98 compiler to be able to use, those aren't an option unless you're going to put a requirement on having boost, which can also be undesirable. And if you actually want the map to have sole ownership of its contents then you don't want to be using reference_wrapper or most implementations of smart pointers.
Regarding the "latter":
If you want a map to pointers that auto deletes pointed at memory, then reusing "all" other map behavior and overriding clear makes a lot of sense to me, of course then you'll also want to override assignment/copy constructors to clone the pointed to objects when you copy the map so that you don't double delete a pointed to instance of the valueClass
.
But that's only requires an extremely small amount of coding to implement.
I also use a protected typedef std::map
as the first 2 lines of the declaration of the derived class map, so that that that I can call baseClassMap::clear();
in the overridden clear()
function after the iterator loop deletes all instances of valueClass*
contained in the derived map, which make maintenance easier in case the type of valueClass*
ever changes.
The point is, while it may have limited applicability in good coding practice, I don't think that it is fair to say that it is NEVER a good idea to descend from map. But maybe you have a better idea that I haven't thought of about how to achieve the same automatic memory management effect without adding a significant amount of additional source code (e.g. aggregating a std::map
).