Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't STL containers have virtual destructors?

Does anyone know why the STL containers don't have virtual destructors?

As far as I can tell, the only benefits are:

  • it reduces the size of an instance by one pointer (to the virtual method table) and
  • it makes destruction and construction a tiny bit faster.

The downside is that it's unsafe to subclass the containers in the usual way.

EDIT: Perhaps my question could be rephrased "Why weren't STL containers designed to allow for inheritance?"

Because they don't support inheritance, one is stuck with the following choices when one wants to have a new container that needs the STL functionality plus a small number of additional features (say a specialized constructor or new accessors with default values for a map, or whatever):

  • Composition and interface replication: Make a new template or class that owns the STL container as a private member and has one pass-through inline method for each STL method. This is just as performant as inheritance, avoids the cost of a virtual method table (in the cases where that matters). Unfortunately, the STL containers have fairly broad interfaces so this requires many lines of code for something that should seemingly be easy to do.
  • Just make functions: Use bare (possibly templated) file-scoped functions instead of trying to add member functions. In some ways this can be a good approach, but the benefits of encapsulation are lost.
  • Composition with public STL access: Have the owner of the STL container let users access the STL container itself (perhaps guarded through accessors). This requires the least coding for the library writer, but it's much less convenient for users. One of the big selling points for composition is that you reduce coupling in your code, but this solution fully couples the STL container with the owner container (because the owner returns a true STL container).
  • Compile-time polymorphism: Can be somewhat tricky to do write, requires some code gymnastics, and isn't appropriate for all situations.

As a side question: is there a standards-safe way of subclassing with non-virtual destructors (let's assume that I don't want to override any methods, just that I want to add new ones)? My impression is that there is no generic and safe way of doing this if one does not have the power to change the code defining the non-virtual class.

EDIT 2:

As @doc points out, C++ 11's fancier using declarations lower the cost of composition somewhat.

like image 456
Mr Fooz Avatar asked Oct 30 '09 00:10

Mr Fooz


People also ask

Why we have virtual destructor but not virtual constructor?

Virtual Constructor in C++ In C++, the constructor cannot be virtual, because when a constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual. But virtual destructor is possible.

Can we have virtual destructors?

Yes, it is possible to have a pure virtual destructor. Pure virtual destructors are legal in standard C++ and one of the most important things to remember is that if a class contains a pure virtual destructor, it must provide a function body for the pure virtual destructor.

When should virtual destructors be used?

Virtual destructors in C++ are used to avoid memory leaks especially when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects.

Is STL container thread safe?

The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses to distinct containers are safe, and simultaneous read accesses to to shared containers are safe.


1 Answers

A virtual destructor is only useful for inheritance scenarios. STL containers are not designed to be inherited from (nor is it a supported scenario). Hence they don't have virtual destructors.

like image 52
JaredPar Avatar answered Sep 23 '22 04:09

JaredPar