patterncppMinor
Simple C++ object pool
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); //
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:
and at the acquire change the return line:
The above will improve the efficiency of the release operation, as you don't need to search for the element.
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.