I inherited from C++ STL container and add my own methods to it. The rationale was such that to the clients, it will look act a regular list, yet has application-specific me
why you need extend vector in this way?
use standard <algorithm>
with your functors.
e.g.
std::min_element, std::max_element
int max_a = std::max_element
(
v.begin(),
v.end(),
boost::bind(
std::less< int >(),
bind( &Item::a, _1 ),
bind( &Item::a, _2 )
)
)->a;
std::accumulate - for calculate avarage
const double avg_c = std::accumulate( v.begin(), v.end(), double( 0 ), boost::bind( Item::c, _1 ) ) / v.size(); // ofcourse check size before divide
your ItemList::SpecialB() could be rewrited as:
int accumulate_func( int start_from, int result, const Item& item )
{
if ( item.SpecialB() < start_from )
{
result -= item.SpecialB();
}
return result;
}
if ( v.empty() )
{
throw sometghing( "empty vector" );
}
const int result = std::accumulate( v.begin(), v.end(), v.front(), boost::bind( &accumulate_func, v.front(), _1, _2 ) );
BTW: if you don't need access to members, you don't need inheritance.
If the standard algorithms don't have what you need, just write free functions, preferably templated.
I prefer to use stl containers as an implementation detail rather than as part of my solution's interface. This way I can change containers (vector for deque or list) if the need arises without any of the calling code being affected. You may have to write a few call through functions but the encapsulation is worth the extra typing.
This is a bad idea.
There are a lot of reasons you shouldn't derive from STL classes, foremost of which is that they're not designed for it. Vector doesn't have a virtual destructor, so if you extend it, the superclass's destructor may not be called properly and you'll get memory leaks.
For more on this, see this answer on why not to derive from std::string
. Many of the same points apply:
Constructor doesn’t work for class inherited from std::string
std::vector
is assignable, but if you add your own fields they won't get copied on assignment if you assign from a vector pointer or vector reference. This is because vector
's operator=
does not know about your fields.For all of these reasons, you're better off making utility functions than extending when it comes to STL.
Warnings about not inheriting from STL containers appear because methods of STL containers are not virtual. So if you don't override methods and don't need polymorphic behaviour, but just extend the class — it's OK to inherit STL containers.
I can't see why you need to extend vector with those methods. You could just write them as standalone functions, eg:
int MaxA(const std::vector<Item>& vec) {
if(vec.empty()) {
throw;
}
int maxA = vec[0].a;
for(std::vector<Item>::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if(i->a > maxA) {
maxA = i->a;
}
}
return maxA;
}
Or there's std::max_element which would do much the same... minus the throwing of course.