patterncppMinor
Simple object pool template container in C++
Viewed 0 times
simpletemplatecontainerpoolobject
Problem
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.
What do you think ?
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
#include
#define itv(TYPE) std::vector::iterator
using namespace std;
template
struct object_pool
{
std::vector pool;
std::queue 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 ?
Solution
Don't do this:
In anything other than a toy this will cause problems.
I don't like this:
With C++11 this type if thing has been resolved by
I would also define the iterator in terms of the object pool:
I would hide the fact that internally the
To access elements I would also provide const version
The methods that can be const should be const:
The implementation details are fine.
I would change the add() so it returned pos:
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:
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
using namespace std;In anything other than a toy this will cause problems.
I don't like this:
#define itv(TYPE) std::vector::iteratorWith C++11 this type if thing has been resolved by
auto.I would also define the iterator in terms of the object pool:
template
struct object_pool
{
typedef std::vector::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 object_pool
{
std::vector pool;
std::queue avail;
public:
typedef std::vector::iterator iterator;
typedef std::vector::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
Code Snippets
using namespace std;#define itv(TYPE) std::vector<TYPE>::iteratortemplate <class TYPE>
struct object_pool
{
typedef std::vector<TYPE>::iterator iterator;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();}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);}Context
StackExchange Code Review Q#13979, answer score: 7
Revisions (0)
No revisions yet.