In this recipe, we will create a simple implementation of an object pool and learn how to use it in your applications:
- In your working ~/test directory, create a subdirectory called objpool.
- Use your favorite text editor to create a objpool.cpp file in the objpool subdirectory. Let's define a templated ObjectPool class. We start with the private data members and a constructor:
#include <iostream>
template<class T, size_t N>
class ObjectPool {
private:
T objects[N];
size_t available[N];
size_t top = 0;
public:
ObjectPool(): top(0) {
for (size_t i = 0; i < N; i++) {
available[i] = i;
}
}
- Now let's add a method to get elements from the pool:
T& get() {
if (top < N) {
size_t idx = available[top++];
return objects[idx];
} else {
throw std::runtime_error("All objects are in use");
}
}
- Next, we add a method that returns an element to the pool:
void free(const T& obj) {
const T* ptr = &obj;
size_t idx = (ptr - objects) / sizeof(T);
if (idx < N) {
if (top) {
top--;
available[top] = idx;
} else {
throw std::runtime_error("Some object was freed more than once");
}
} else {
throw std::runtime_error("Freeing object that does not belong to
the pool");
}
}
- Then, wrap up the class definition with a small function that returns the number of elements that are requested from the pool:
size_t requested() const { return top; }
};
- Define a data type to be stored in the object pool as shown in the following code:
struct Point {
int x, y;
};
- Then add code that works with the object pool:
int main() {
ObjectPool<Point, 10> points;
Point& a = points.get();
a.x = 10; a.y=20;
std::cout << "Point a (" << a.x << ", " << a.y << ") initialized, requested " <<
points.requested() << std::endl;
Point& b = points.get();
std::cout << "Point b (" << b.x << ", " << b.y << ") not initialized, requested " <<
points.requested() << std::endl;
points.free(a);
std::cout << "Point a(" << a.x << ", " << a.y << ") returned, requested " <<
points.requested() << std::endl;
Point& c = points.get();
std::cout << "Point c(" << c.x << ", " << c.y << ") not intialized, requested " <<
points.requested() << std::endl;
Point local;
try {
points.free(local);
} catch (std::runtime_error e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
}
- Create a file called CMakeLists.txt in the loop subdirectory with the following content:
cmake_minimum_required(VERSION 3.5.1)
project(objpool)
add_executable(objpool objpool.cpp)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
SET(CMAKE_CXX_FLAGS "--std=c++11")
set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)
- Build the application and copy the resulting executable binary to the target system. Use recipes from Chapter 2,Setting Up the Environment, to do it.
- Switch to the target system terminal. Log in using user credentials, if needed.
- Run the binary.