c++ - Is it okay to inherit implementation from STL containers, rather than delegate? -


i have class adapts std::vector model container of domain-specific objects. want expose of std::vector api user, he/she may use familiar methods (size, clear, at, etc...) , standard algorithms on container. seems reoccurring pattern me in designs:

class mycontainer : public std::vector<myobject> { public:    // redeclare container traits: value_type, iterator, etc...     // domain-specific constructors    // (more useful user std::vector ones...)     // add few domain-specific helper methods...     // perhaps modify or hide few methods (domain-related) }; 

i'm aware of practice of preferring composition inheritance when reusing class implementation -- there's gotta limit! if delegate std::vector, there (by count) 32 forwarding functions!

so questions are... bad inherit implementation in such cases? risks? there safer way can implement without typing? heretic using implementation inheritance? :)

edit:

what making clear user should not use mycontainer via std::vector<> pointer:

// non_api_header_file.h namespace detail {    typedef std::vector<myobject> myobjectbase; }  // api_header_file.h class mycontainer : public detail::myobjectbase {    // ... }; 

the boost libraries seem stuff time.

edit 2:

one of suggestions use free functions. i'll show here pseudo-code:

typedef std::vector<myobject> mycollection; void specialcollectioninitializer(mycollection& c, arguments...); result specialcollectionfunction(const mycollection& c); etc... 

a more oo way of doing it:

typedef std::vector<myobject> mycollection; class mycollectionwrapper { public:    // constructor    mycollectionwrapper(arguments...) {construct coll_}     // access collection directly    mycollection& collection() {return coll_;}     const mycollection& collection() const {return coll_;}     // special domain-related methods    result myspecialmethod(arguments...);  private:    mycollection coll_;    // other domain-specific member variables used    // in conjunction collection. } 

the risk deallocating through pointer base class (delete, delete[], , potentially other deallocation methods). since these classes (deque, map, string, etc.) don't have virtual dtors, it's impossible clean them pointer classes:

struct badexample : vector<int> {}; int main() {   vector<int>* p = new badexample();   delete p; // undefined behavior   return 0; } 

that said, if you're willing make sure never accidentally this, there's little major drawback inheriting them—but in cases that's big if. other drawbacks include clashing implementation specifics , extensions (some of may not use reserved identifiers) , dealing bloated interfaces (string in particular). however, inheritance intended in cases, container adapters stack have protected member c (the underlying container adapt), , it's accessible derived class instance.

instead of either inheritance or composition, consider writing free functions take either iterator pair or container reference, , operate on that. practically of <algorithm> example of this; , make_heap, pop_heap, , push_heap, in particular, example of using free functions instead of domain-specific container.

so, use container classes data types, , still call free functions domain-specific logic. can still achieve modularity using typedef, allows both simplify declaring them , provides single point if part of them needs change:

typedef std::deque<int, myallocator> example; // ... example c (42); example_algorithm(c); example_algorithm2(c.begin() + 5, c.end() - 5); example::iterator i; // nested types easier 

notice value_type , allocator can change without affecting later code using typedef, , container can change deque vector.


Comments

Popular posts from this blog

serialization - Convert Any type in scala to Array[Byte] and back -

matplotlib support failed in PyCharm on OSX -

python - Matplotlib: TypeError: 'AxesSubplot' object is not callable -