HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Simple C++ object pool

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
poolobjectsimple

Problem

I am studying computer science and just for the sake of practise I thought of implementing an object pool.

This is my first implementation, it is simple and works correctly, but I would love any thoughts on it. Currently, the memory is allocated on the stack, but I am thinking of using policy based design to allow heap allocation as well.

Here is the code of the pool:

```
#include
#include
#include

/**
* Generic class for object pools.
*/
template class StackObjectPool {
public:
using pointer = std::unique_ptr >;
using PoolType = StackObjectPool;

StackObjectPool() {}
StackObjectPool(const PoolType& orig) = delete;
~StackObjectPool() {}

/**
* Acquires an object not being currently used
* @return pointer to the acquired object
* @throw std::out_of_range if all the objects inside the pool are being used
*/
pointer acquire() {
unsigned int index = 0; // look for the first free object
while(m_occupied_registry[index]) ++index;
if(index >= SZ) throw std::out_of_range("Pool exceeded its size");
m_occupied_registry[index] = true; // mark it as currently in use
m_initialiser(&m_objects[index]); // initialise it

//return an unique_ptr that calls release when reset
return pointer(&m_objects[index], this->void{release(element);});
}

friend std::ostream& operator<<(std::ostream& ostream, const PoolType& pool) {
for(unsigned int index = 0; index < SZ; ++index) {
std::cout<<(pool.m_occupied_registry[index]?"[occupied] ":"[free]\n");
if(pool.m_occupied_registry[index]) {
std::cout<<pool.m_objects[index]<<"\n";
}
}
return ostream;
}
private:

void release(T* element) {
unsigned int index = 0;
while(&m_objects[index] != element) ++index;
m_occupied_registry[index] = false; // mark the released element as free
m_releaser(element); //

Solution

You might change:

void release(T* element, unsigned int index) {
    if (&m_objects[index] != element) {
            std::cerr << "no match index and element\n";
            return; // or exit(1);
    }
    m_occupied_registry[index] = false; // mark the released element as free
    m_releaser(element); // call release functor
}


and at the acquire change the return line:

return pointer(&m_objects[index], [this,index](T* element)->void{release(element,index);});


The above will improve the efficiency of the release operation, as you don't need to search for the element.

Code Snippets

void release(T* element, unsigned int index) {
    if (&m_objects[index] != element) {
            std::cerr << "no match index and element\n";
            return; // or exit(1);
    }
    m_occupied_registry[index] = false; // mark the released element as free
    m_releaser(element); // call release functor
}
return pointer(&m_objects[index], [this,index](T* element)->void{release(element,index);});

Context

StackExchange Code Review Q#152431, answer score: 4

Revisions (0)

No revisions yet.