Thou shalt not inherit from std::vector
Ok, this is really difficult to confess, but I do have a strong temptation at the moment to inherit from std::vector
.
I need about 10 customized algorithms for vector and I want them to be directly members of the vector. But naturally I want also to have the rest of std::vector
's interface. Well, my first idea, as a law-abiding citizen, was to have an std::vector
member in MyVector
class. But then I would have to manually reprovide all of the std::vector's interface. Too much to type. Next, I thought about private inheritance, so that instead of reproviding methods I would write a bunch of using std::vector::member
's in the public section. This is tedious too actually.
And here I am, I really do think that I can simply inherit publicly from std::vector
, but provide a warning in the documentation that this class should not be used polymorphically. I think most developers are competent enough to understand that this shouldn't be used polymorphically anyway.
Is my decision absolutely unjustifiable? If so, why? Can you provide an alternative which would have the additional members actually members but would not involve retyping all of vector's interface? I doubt it, but if you can, I'll just be happy.
Also, apart from the fact that some idiot can write something like
std::vector<int>* p = new MyVector
is there any other realistic peril in using MyVector? By saying realistic I discard things like imagine a function which takes a pointer to vector ...
Well, I've stated my case. I have sinned. Now it's up to you to forgive me or not :)
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 (eg should keep some state).
The problem is that MyVector
is a new entity. It means a new C++ developer should know what's 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.
The whole STL was designed in such way that algorithms and containers are separate .
This led to a concept of different types of iterators: const iterators, random access iterators, etc.
Therefore I recommend you to accept this convention and design your algorithms in such way that they won't care about what is the container they're working on - and they would only require a specific type of iterator which they'd need to perform their operations.
Also, let me redirect you to some good remarks by Jeff Attwood .
The main reason for not inheriting from std::vector publicly is an absence of virtual destructor that effectively prevents you from polymorphic use of descendants. In particular, you are not allowed to delete
a std::vector<T>*
that actually points at a derived object (even if the derived class adds no members), yet the compiler generally can't warn you about it.
Private inheritance is allowed under these conditions. I therefore recommend to use private inheritance and forward required methods from the parent as shown below.
class AdVector: private std::vector<double>
{
typedef double T;
typedef std::vector<double> vector;
public:
using vector::push_back;
using vector::operator[];
using vector::begin;
using vector::end;
AdVector operator*(const AdVector & ) const;
AdVector operator+(const AdVector & ) const;
AdVector();
virtual ~AdVector();
};
You should first consider refactor your algorithms to abstract from type of container they are operating on and leave them as free templated functions as pointed out by majority of answerers. This usually done by making an algorithm accept a pair of iterators instead of container as arguments.
链接地址: http://www.djcxy.com/p/9136.html上一篇: 那个文本区域是无效的
下一篇: 你不应该从std :: vector继承