Overal Goal
I'm writing a storage library for an embedded system with no dynamic memory allocation which handles the storage of several different types of objects in a single array / pool of static memory. The objects should behave as if they are members of each other.
The number of objects is unknown. The data comes from a structured source so it only needs to be added to the store once. Data gets added sequentially but needs to be read arbitrarily.
Specific Problem
Each object is a simple class but instances of these classes need to access the shared storage pool.
My solution
I set up an array of unions which contain the simple POD objects, all of which have similar size. These objects store their children's location within the pool as private members. The two different types grow from opposite sides so only the total number of objects is limited.
Adding to the store can be done through the main class, which needs to access these private members so the main class is declared a friend in the object class.
However, the objects can't access the main's storage pool so for now I've declared the storage pool outside the class. I don't want to store a pointer in the objects to the store because of the overhead. Only one store needs to exist at a time.
Code (for C++11)
The below is working code but it doesn't prevent the storage pool from being accessed. So is there a better way?
#include <cstdio>
#include <cstdint>
namespace Store{
const int STORE_SIZE = 512;
// 8 bytes
class Chair {
public:
int a;
int n_legs;
};
// 8 bytes
class Room {
friend class Flat;
private:
uint16_t chairs_start;
public:
uint16_t number_of_chairs;
int a;
int b;
// member functions
Chair getChair( int idx );
};
// 8 byte element of storage can be either one or the other
union Element{
Chair chair;
Room room;
};
union Element;
Element pool[STORE_SIZE];
Chair Room::getChair( int idx )
{
return pool[chairs_start - idx].chair; // needs access to pool!
}
class Flat{
public:
void addRoom() {
Room room;
room.chairs_start = pool_next_chair;
pool[pool_next_room++].room = room;
}
void addChair() {
Chair chair;
chair.a = pool_next_chair; // only for testing
pool[pool_next_chair--].chair = chair; // add chair to pool from other side
// incremente chair count for last added room
pool[pool_next_room - 1].room.number_of_chairs++;
}
Room getRoom( int idx ){
return pool[idx].room;
}
private:
uint16_t pool_next_room = 0;
const uint16_t pool_first_chair = STORE_SIZE - 1;
uint16_t pool_next_chair = pool_first_chair;
};
}
int main() {
Store::Flat flat;
flat.addRoom();
flat.addChair();
flat.addChair();
flat.addRoom();
flat.addChair();
auto room2 = flat.getRoom(1);
auto chair1 = room2.getChair(0);
printf("Got chairs %d and %d\n",chair1.a, flat.getRoom(0).getChair(1).a);
// Got chairs 509 and 510
return 0;
}
The code works but leaves the pool accessible. In general, is there a better layout or structuring I could use which results in a similar manner of simple access like in the above main() function?
Any other code quality comments are highly welcome! Thanks a lot!