Sign in to follow this  
Lode

Inheriting from std::vector

Recommended Posts

Inheriting from std::vector is evil because it hasn't got a virtual destructor. However, what if you really want to inherit from it and implement a custom destructor for your inherited one? Are there ways to reduce the evilness? The problem is that if you cast to std::vector and then destruct it, that the destructor of the inheriting class isn't called, is this correct? Are there other problems too? If so, can it be avoided that you can cast to std::vector somehow?

Share this post


Link to post
Share on other sites
Quote:
Original post by Lode
Inheriting from std::vector is evil because it hasn't got a virtual destructor.

However, what if you really want to inherit from it and implement a custom destructor for your inherited one? Are there ways to reduce the evilness?

The problem is that if you cast to std::vector and then destruct it, that the destructor of the inheriting class isn't called, is this correct? Are there other problems too?

If so, can it be avoided that you can cast to std::vector somehow?


Prefer composition to inheritance. STL containers really weren't meant to be extended in this manner, so it's better not to use them in this way.

You can implement an STL-like interface with simply delegates the functionality to the vector member. It's more typing, but less risky.

Share this post


Link to post
Share on other sites
You don't need the virtual destructor, unless you're going to use polymorphic behaviour (ie. use your deriving vector through a std::vector<T>*).
link: c++ faq

[Edited by - Koen on March 7, 2008 9:48:41 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
You can inherit non-publically.


Something like this:
Quote:

template <class T, class A>
class vector_base : std::vector<T,A>
{
public:
virtual ~vector_base(){}
using std::vector::...
};


Now you've got a class that behaves exactly like std::vector, except it has a virtual d'tor.

Quote:

You don't need the virtual destructor, unless you're going to use polymorphic behaviour (ie. use your deriving vector through a std::vector<T>*).
link: c++ faq


It's frowned upon, as you typically wouldn't get any error or warning from casting to std::vector<T>* and you may only realsie your mistake when bug reports start rolling in.

Share this post


Link to post
Share on other sites
Quote:
Original post by Koen
You don't need the virtual destructor, unless you're going to use polymorphic behaviour (ie. use your deriving vector through a std::vector<T>*).
link: c++ faq


The downside is in the case where it doesn't work, it's a very subtle bug that's not easy to detect.

Share this post


Link to post
Share on other sites
The only problem I can think of is if you start doing stuff like this:

class MyDerivingVector: public std::vector<T>
{
public:

~MyDerivingVector()
{
//...
}

};

std::vector<T>* base_pointer = new MyDerivingVector;

//...

delete base_pointer; // --> o-ow!!

But you could argue that a c++ developer should know this is not something you should do: a vector container is not a polymorphic object. The same thing happens for example with geometric point and vector classes with templatized bases, and in that case no one seems to mind.
Or am I missing something else, that can cause bugs/problems?

Share this post


Link to post
Share on other sites
Quote:
Original post by Koen
The only problem I can think of is if you start doing stuff like this:

class MyDerivingVector: public std::vector<T>
{
public:

~MyDerivingVector()
{
//...
}

};

std::vector<T>* base_pointer = new MyDerivingVector;

//...

delete base_pointer; // --> o-ow!!

But you could argue that a c++ developer should know this is not something you should do: a vector container is not a polymorphic object. The same thing happens for example with geometric point and vector classes with templatized bases, and in that case no one seems to mind.
Or am I missing something else, that can cause bugs/problems?


There's really no reason to inherit from std::vector if it's not intended to be used polymorphically. Inherit for interface, not implementation. It's valid to assume that a derived class can be safely used polymorphically, if you derive from it. What's described above is an anti-pattern and a violation of proper object-oriented practices.

For more information, see C++ Coding Standards, Item 34: Prefer Composition to Inheritance and Item 35: Avoid inheriting from classes that were not designed to be base classes.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this