+9  A: 

Because you need a virtual destructor and the std containers don't have it. The std containers are not designed to act as base class.

For more information read the article "Why shouldn't we inherit a class from STL classes?"

Guideline

A base class must have:

  • a public virtual destructor
  • or a protected non-virtual destructor
TimW
That applies when you design for run-time polymorphism. There's nothing wrong with deriving from non-virtual classes if you don't intend to treat them as their base types other then strong coupling.
Nikolai N Fetissov
Where in Example B do you see a need for a virtual destructor?
Thomas L Holaday
You can't tell from example B because it's the class declaration and not the use of the class. A user CAN and WILL abuse the class.A base class must have: - a public virtual destructor - or a protected non-virtual destructor
TimW
@Thomas L Holaday: If the classes are declared inside a private section of another class with explicit notes mentioning the problem with virtual destructors then fine. Otherwise sombody somewhere will use them in a way that will requirea virtual destructor and then the code will be impossable to debug and find the real problem.
Martin York
@TimW, can you provide an example of a way a user could abuse B that would not be an identical abuse of A?
Thomas L Holaday
@Thomas, easy going: vector<int> *p = getCharges(); delete p; derive private or put the vector as a member. don't derive public.
Johannes Schaub - litb
@litb, when I step through that code with the debugger, I see no leaks. Do you?
Thomas L Holaday
@Thomas The memory leak is compiler dependent. Your compiler probably didn't add any extra memory for the derived classes but other compliers can.And if somebody else in your team decides that he needs a extra instance variable in the classes, your application will leak.
TimW
@TimW, (1) Adding extra memory for the derived class will cause no leak; the delete operator returns the memory originally allocated, not the sizeof the object at which it is aimed. (2) if someone decides an extra instance variable is required, and the instance variable is a PODS, there will be no leak. If an extra instance variable is needed that requires destruction, then the onus is on the person adding the instance variable to follow the inheritance chain to confirm that the destructor is virtual.
Thomas L Holaday
+15  A: 

The standard containers do not have virtual destructors, thus you cannot handle them polymorphically. If you will not, and everyone who uses your code doesn't, it's not "wrong", per se. However, you are better off using composition anyway, for clarity.

rlbond
When using this practice with STL containers, I've found that private inheritance is a syntactically easier way to express composition.
ASk
+3  A: 

Also, in most cases, you should prefer membership over inheritance if possible.

Trent
Thomas L Holaday
@Thomas L Holaday Of course not; perhaps I should clarify. If you aren't going to be specializing the base class but merely need to use the base class features in your class (as in the example) it is better to have a private member of that class in your class. All the other benefits listed in the question are gained simply by having a class not that fact that it inherited from any other particular class.
Trent
+2  A: 

The issue isn't a philisophical one, it's an implementation issue. The standard containers' destructors aren't virtual, which means there's no way to use runtime polymorphisim on them to get the proper desctructor.

I've found in practice it really isn't that much of a pain to create my own custom list classes with just the methods my code needs defined (and a private member of the "parent" class). In fact, it often leads to better-designed classes.

T.E.D.
+1  A: 

One strong counter-argument, in my opinion, is that you are imposing an interface and the implementation onto your types. What happens when you find out that vector memory allocation strategy does not fit your needs? Will you derive from std:deque? What about those 128K lines of code that already use your class? Will everybody need to recompile everything? Will it even compile?

Nikolai N Fetissov
How does using inheritance more of an imposition of interface and implementation than using a typedef?
Thomas L Holaday
Well, I didn't compare one to the other - was just saying that public derivation is dangerous in this regard. After all, you can hide privately contained vector behind a pimpl, but you cannot hide your ancestors :)
Nikolai N Fetissov
+1  A: 

One word: Substitutability

Johann Gerell
A: 

Aside from the fact that a base class needs a virtual destructor or a protected non-virtual destructor you are making the following assertion in your design:

Rates, and Charges for that matter, ARE THE SAME AS a vector of doubles in your example above. By your own assertion "...as time goes by, Rates and Charges develop personalities..." then is the assertion that Rates ARE STILL THE SAME AS a vector of doubles at this point? A vector of doubles is not a singleton for example therefore if I use your Rates to declare my vector of doubles for Widgets I may incur some headache from your code. What else about Rates and Charges are subject to change? Are any of the base class changes safely insulated from clients of your design should they change in a fundamental way?

The point is a class is an element, of many in C++, to express design intentions. Saying what you mean and meaning what you say is the reason against using inheritance in this manner.

...Or just posted more succinctly before my response: Substitution.

C Johnson