2014-12-09 3 views
5

Я знаю в нормальных условиях, как позаботиться о снятии памяти. Мой случай немного отличается.оператор delete - как реализовать?

Я реализую свой собственный пул памяти. Я хотел бы, чтобы клиент моего класса был как можно ближе к общему методу выделения и де-распределения.

inline void* operator new(size_t dead_param, CPool& objPool) 
{ 
    return objPool.Allocate(); 
} 

я иметь эту глобальную функцию, так что пользователь моего класса может просто вызвать

Base baseObj = new (poolObj)Base2();

Теперь я не знаю, как назвать деструктор? Я clearl понятия не имею

хотя у меня есть глобальный оператор удаления

inline void operator delete(void* ptr, CPool& objPool) 
{ 
    objPool.DeAllocate(ptr); 
} 

пожалуйста, руководство .. как я могу получить эту функцию, вызываемую из клиентского кода? С минимальными изменениями в синтаксисе со стороны пользователя. Также обратите внимание, что я не хочу, чтобы пользователи моего кода реализовывали operator new и operator delete и звонили Allocate и DeAllocate оттуда.

+0

Почему не просто люди называют 'Base * baseObj = poolObj.Allocate();' – Barry

+0

Синтаксис для клиента похоже немного уродливый. 'Base * baseObj = (Base *) poolObj.Allocate()'. Yuck .. typecasting ... что, хотя я сохранил как окончательный вариант .. Кроме того, так как не удалось получить эту функцию, я теперь curous. – Adorn

+5

Удаление места размещения вызывается только из внутреннего размещения new, когда конструктор выходит с исключение. Во всех остальных случаях вызывается «нормальный» оператор delete (void *) '. Вы должны занести достаточную информацию в выделенный блок памяти, чтобы иметь возможность освободить его позже, без дополнительного ввода. Часто распределитель записывал дополнительную информацию с отрицательным смещением от возвращаемого указателя. –

ответ

1

Суть этого: При размещении нового это единственный случай, когда явного вызова деструктора в порядке:

baseObj-> ~ Base();

Но это кажется неуклюжим, потому что, используя свой пул памяти, вы на самом деле заставляете конечного пользователя выполнять всю книгу ... это делает ваш класс пула памяти не лучше (и, возможно, немного хуже), чем просто использование станд :: вектор.

Я бы не пользователя сделать размещение нового сам ... а, если поставлять свой собственный пул памяти, это должно быть сделано жгутами класса ObjectPool:

class ObjectPool { 
    public: 
    template <typename T, typename... A>/*c++ 11 ftw*/ 
    T* allocate(A... args) { 
     void* create_location;//pool figures out where this is, probably with sizeof<T> 

     return new (create_location) T(args...); 
    } 
    template <typename T> 
    void dellocate(T* t) { 
     t.~T();//With placement new, this is the one place this is OK 
     //pool marks that memory as avaiable to be allocated in 
    } 
} 

Честно говоря, это единственный способ для вашего пула будет больше полезности, а конечный пользователь просто сделает свой собственный std::vector<uint8_t>.

Следует отметить, что это не делает ничего, чтобы держать T от выделения что-нибудь еще в куче ...

+0

ok .. возможно, вы можете просветить меня больше на вопрос дизайна http://stackoverflow.com/questions/27375620/generic-memory-pool-how-to-design-issue Я не совсем понимаю, что вы пытаетесь сказать – Adorn

Смежные вопросы