Thou Shalt Not Inherit from Std::Vector

Thou shalt not inherit from std::vector

Actually, there is nothing wrong with public inheritance of std::vector. If you need this, just do that.

I would suggest doing that only if it is really necessary. Only if you can't do what you want with free functions (e.g. should keep some state).

The problem is that MyVector is a new entity. It means a new C++ developer should know what the hell it is before using it. What's the difference between std::vector and MyVector? Which one is better to use here and there? What if I need to move std::vector to MyVector? May I just use swap() or not?

Do not produce new entities just to make something to look better. These entities (especially, such common) aren't going to live in vacuum. They will live in mixed environment with constantly increased entropy.

Inheriting from std::vector

I think this answer perfectly answers your question.

It's not impossible to inherit from std::vector, it just probably would be very limited (due to no virtual destructor), quite confusing to others and extending by composition would be better/easier/more maintainable than inheritance anyway.

Perhaps Stroustrup simply wanted to show it's doable, but not necessarily to imply that he suggests it.

Inheriting from std:: vector

If the function in question isn't overridden in the derived class, you
can just call it:

void HistoGram::clear()
{
at( 0 ) = 0;
// ...
}

This is also true for operators, but you'll have to use (*this) as the
left hand operator:

void HistoGram::clear()
{
(*this)[0] = 0;
// ...
}

If the function or operator is overridden, you'll either have to
qualify the function name,

void HistoGram::clear()
{
std::vector<int>::at( 0 ) = 0;
// ...
}

or cast the this pointer to the base class type:

void HistoGram::clear()
{
(*static_cast<std::vector<int>*>( this ))[0] = 0;
// ...
}

But are you sure that you want public inheritance here? You state that
the size of the vector should always be 6. There's no way you can
guarantee that using public inheritance; at the least, you need private
inheritance, and then using declarations for the operations that you
want to support. (I've a couple of cases where I've needed restricted
std::vector like this, which I've implemented using private
inheritance. And sometimes forwarding functions, when for example
I've wanted to expose only the const version of the function.)

Also: there are very, very few cases where std::vector<>::at is
appropriate. Are you sure you don't want [], with the bounds checking
you get in most modern implementations.

Should a user-defined container that is a wrapper for std::vector, inherit or contain std::vector?

First of all, STL containers are not supposed to be inherited. They even don't have virtual destructors.

Second, it's always preferable to choose composition/aggregation in favor of inheritance, as this is a lower coupling technique that puts less restrictions/requirements on the code.

See this answer for more details, this question has been raised a lot of times.

Remove some, but not all overloaded functions inherited from base class

From the comments:

Using v[0]->m will call the const-version of the operator if v is const. Otherwise it calls the non-const operator.

The fact that you don't write to v doesn't affect this.

C++ Create class that inherits a Vector

I would like to know if I can create a class that inherits a vector that contains vectors (2d) and can write my own methods

Yes, nothing prohibits this although it's generally recommended to use composition instead. One reason why it's not recommended is that the standard containers destructor is not virtual so deleting objects though base class pointers doesn't work.

C++ Inheritance Overriding Vector Member Variable

No, that is not possible.

As one user pointed it it looks like a XY problem. You should better explain what you want to achieve.

Given only the few explanation...

One solution is to use std::vector<Foo*> objects; in FooManager and in BarManager to have functions that take objects and cast the pointers in objects to Bar*.

class BarManager : public FooManager {
Bar* get_at_index(std::size_t i) const { return static_cast<Bar*>(objects[i]); }
}

Another approach is to use a templated class and then use either Manager<Foo> mgr; or Manager<Bar> mgr;.

template <class T>
class Manager
{
public:
std::vector<T*> objects;
}


Related Topics



Leave a reply



Submit