Sign in to follow this  
all_names_taken

Storing polymorphic objects in STL containers

Recommended Posts

Any tips/idioms on how to store polymorphic objects in STL containers in C++? Example:
class B { ... };
class C : public B { ... };
class D : public B { ... };
In this scenario, I would like to make a vector containing a mix of B, C and D objects. If I make a
vector<B> 
, all objects would be of static type B so it wouldn't work, right? And if I make a
vector<B*>
, I need extra outside code for handling memory allocation/deallocation of B, C, and D objects, which ruins the whole idea of abstract data structures that encapsulate everything, unless I write a very complex wrapper or inherited version of vector. Any ideas/standard ways for dealing with this kind of problem in an elegant, encapsulated way?

Share this post


Link to post
Share on other sites
Ok, thanks! Thinking about it again, I realize that the problem couldn't really have been solved in an easy general encapsulated way, since because I have multiple class types, I would need different allocators for each class to get any more effective than a series of heap allocations. So, shared_pointer can improve the safety problems with the pointer, but if I want more efficient allocation too, perhaps it's time for me to write a templated "slab allocator" class?

Share this post


Link to post
Share on other sites
Make it work, make it maintainable, make it flexible, make it fast.

If the first three are done, then sure some sort of custom allocator might be prudent depending on your situation; otherwise it's fairly easy enough to drop in later once you get everything else working and see that the allocations are a performance problem.

Share this post


Link to post
Share on other sites
Quote:
Original post by all_names_taken
Ok, thanks! Thinking about it again, I realize that the problem couldn't really have been solved in an easy general encapsulated way, since because I have multiple class types, I would need different allocators for each class to get any more effective than a series of heap allocations. So, shared_pointer can improve the safety problems with the pointer, but if I want more efficient allocation too, perhaps it's time for me to write a templated "slab allocator" class?


Be careful not to optimize prematurely. As Donald Knuth once said "Premature optimization is the root of all evil" and by all means it really is!

That said, if you really need the extra boost in performance you might also use already written and tested libraries instead of developing your own. Boost also provides some nifty allocators (namely boost::pool_allocator and boost::fast_pool_allocator) that you might want to take a look at. Here's a link.

I quote:
Quote:

pool_allocator is a more general-purpose solution, geared towards efficiently servicing requests for any number of contiguous chunks. fast_pool_allocator is also a general-purpose solution, but is geared towards efficiently servicing requests for one chunk at a time; it will work for contiguous chunks, but not as well as pool_allocator. If you are seriously concerned about performance, use fast_pool_allocator when dealing with containers such as std::list, and use pool_allocator when dealing with containers such as std::vector.

Share this post


Link to post
Share on other sites
I dont know what a 'slab allocator' is although i have written custom allocators for stl containers
when i have needed to (you really really shouldnt need to).

whats wrong with

vector< shared_ptr< Base> > ia;

this gives you a fast encapsulated vector of objects of polymorphic type. The allocator is only
allocating the shared_ptr types and not the underlying type. there are no expensive copy constructors
being used for the Base type since the instances are being managed by the shared pointer. you cannot
really get anything more optimised if by optimised you are talking about speed.


I normally define the shared pointer type within the object which i think leads to clearer syntax
ie

vector< Base::shared_ptr_type> ia;

alternatively use
vector< boost::any > ia;

if you want to stores types without a common derivation sub type.
<edit for clarity>

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