# Simple object pool template container in C++

The main advantage of this pattern is when I often create and destroy objects, which in this case are often used.

I made this because I needed to track several short timers at the same time, but it can also be used for stuff like missiles or else.

#include <vector>
#include <queue>

#define itv(TYPE) std::vector<TYPE>::iterator

using namespace std;
template <class TYPE>
struct object_pool
{
std::vector<TYPE> pool;
std::queue<size_t> avail;
TYPE & operator[](const size_t & i) { return pool[i]; }
void add(size_t & pos)
{
if(avail.empty()) // no reusable object
{ pool.push_back(TYPE()); pos = pool.size()-1; }
else
{ pos = avail.back(); avail.pop(); }
}
void rem(size_t & a) { avail.push(a); }
size_t size() { return pool.size(); }
};


What do you think ?

Don't do this:

using namespace std;


In anything other than a toy this will cause problems.

I don't like this:

#define itv(TYPE) std::vector<TYPE>::iterator


With C++11 this type if thing has been resolved by auto.

I would also define the iterator in terms of the object pool:

template <class TYPE>
struct object_pool
{
typedef std::vector<TYPE>::iterator  iterator;


I would hide the fact that internally the object_pool uses a vector and queue. I would then add the obligatory functions to extract information:

template <class TYPE>
class object_pool
{
std::vector<TYPE> pool;
std::queue<size_t> avail;

public:
typedef std::vector<TYPE>::iterator       iterator;
typedef std::vector<TYPE>::const_iterator const_iterator;

iterator       begin()       { return pool.begin();}
iterator       end()         { return pool.end();}
const_iterator begin() const { return pool.begin();}
const_iterator end()   const { return pool.end();}


To access elements I would also provide const version

    TYPE&       operator[](std::size_t index)       { return pool[index];}
TYPE&       at(std::size_t index)               { return pool.at(index);}

TYPE const& operator[](std::size_t index) const { return pool[index];}
TYPE const& at(std::size_t index) const         { return pool.at(index);}


The methods that can be const should be const:

    size_t size() const { return pool.size(); }
//  ^^^^^^^


The implementation details are fine.

    void add(size_t & pos)
{
if(avail.empty()) // no reusable object
{ pool.push_back(TYPE()); pos = pool.size()-1; }
else
{ pos = avail.back(); avail.pop(); }
}
void rem(size_t & a) { avail.push(a); }


I would change the add() so it returned pos:

    size_t add();


Also the vector starts off very small and re-sizes to get bigger.
To make sure that it does not re-size too often I would add a constructor that gives the vector a reasonable size to start with:

object_pool::object_pool()
{
pool.reserve(1000);
}


But I think you are using the wrong technique.
I would use a pool allocator and plug it into the vector.

You can read more about it here: https://stackoverflow.com/q/2984434/14065

• boost seems like a little complicated for what I want to do with do with it. – jokoon Jul 25 '12 at 16:22
• You don't need to use boost. But implementing an allocator would seem a better solution (and also quicker). Though it adds some extra complexity you probably don't need. You need to way complexity against the added advantage for your particular situation. Note: by learning how to use allocators makes your use of the STL more effective. – Martin York Jul 25 '12 at 17:44