Я работаю над реализацией пула памяти / распределителя памяти и настраиваю его в поместье, где из пула может извлекаться только объект особого типа «Клиент». Клиент может быть либо построен непосредственно в пуле, либо он может используйте пул для вызовов динамической памяти, или теоретически он может делать и то, и другое. Я хотел бы иметь возможность перегрузить operator new и operator delete таким образом, чтобы мои пулы вызывали функции alloc () и free (), чтобы получить память, необходимую для построения объекта.
Одна из основных проблем, с которыми я сталкиваюсь, - это получение моего оператора delete, чтобы он мог освободить память, вызвав функцию pool-> free (), которую я написал. Я придумал хак, который исправляет это, передавая пул в конструктор и заставляя деструктор выполнять работу по освобождению. Это все нормально, пока кому-то не понадобится наследовать от этого класса и переопределить деструктор для своих собственных нужд, а затем забыть об освобождении памяти. Вот почему я хочу обернуть все это операторами, чтобы функциональность была скрыта и унаследована по умолчанию.
Мой код находится на GitHub здесь: https://github.com/zyvitski/Pool
Мое определение класса для клиента выглядит следующим образом:
class Client
{
public:
Client();
Client(Pool* pool);
~Client();
void* operator new(size_t size,Pool* pool);
void operator delete(void* memory);
Pool* m_pPool;
};
И реализация:
Client::Client()
{
}
Client::Client(Pool* pool)
{
m_pPool = pool;
}
Client::~Client()
{
void* p = (void*)this;
m_pPool->Free(&p);
m_pPool=nullptr;
}
void* Client::operator new(size_t size, Pool* pool)
{
if (pool!=nullptr) {
//use pool allocator
MemoryBlock** memory=nullptr;
memory = pool->Alloc(size);
return *memory;
}
else throw new std::bad_alloc;
}
void Client::operator delete(void* memory)
{
//should somehow free up the memory back to the pool
// the proper call will be:
//pool->free(memory);
//where memory is the address that the pool returned in operator new
}
Вот пример Main (), который я использую сейчас:
int main(int argc, const char * argv[]){
Pool* pool = new Pool();
Client* c = new(pool) Client(pool);
/*
I'm using a parameter within operator new to pass the pool in for use and i'm also passing the pool as a constructor parameter so i can free up the memory in the destructor
*/
delete c;
delete pool;
return 0;
}
Пока мой код работает, но я хочу знать, есть ли лучший способ добиться этого? Пожалуйста, дайте мне знать, если что-то, о чем я прошу / делаю, просто невозможно, это плохая практика или просто глупо. Я использую MacBook Pro прямо сейчас, но я хотел бы, чтобы мой код был кросс-платформенным, если это вообще возможно.
Если у вас есть какие-либо вопросы, которые помогут вам помочь мне, дайте мне знать.
И, конечно же, заранее спасибо всем, кто может помочь.