2014-12-09 20 views
5

So in circostanze normali come occuparmi della disallocazione della memoria. Il mio caso è leggermente diverso.delete operatore - come implementare?

Sto implementando il mio pool di memoria. Vorrei che il cliente della mia classe fosse il più vicino al metodo generale di allocazione e disallocazione.

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

ho questo funzione globale, in modo che l'utente della mia classe può semplicemente chiamare

Base baseObj = new (poolObj)Base2();

Ora non so come chiamare distruttore? I clearl ho idea di

se ho operatore globale delete

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

si prega di guida .. come posso ottenere questa funzione chiamata dal codice cliente? Con modifiche minime alla sintassi dal lato utente. Si noti inoltre che non voglio che gli utenti del mio codice implementino operator new e operator delete e chiamino da questo numero Allocate e DeAllocate.

+0

Perché non solo sono persone chiamare 'Base * baseObj = poolObj.Allocate();' – Barry

+0

sintassi per il cliente sembra poco brutto. 'Base * baseObj = (Base *) poolObj.Allocate()'. Yuck .. typecasting ... che sebbene io abbia mantenuto come ultima risorsa .. Anche dal momento che non riesco a ottenere questa funzione chiamata, sono curioso ora .. – Adorn

+5

Il posizionamento delete è sempre chiamato dal posizionamento interno nuovo, quando un costruttore esce con un'eccezione. In tutti gli altri casi, viene chiamato un operatore "normale" 'delete (void *)'. Si suppone che si debbano immagazzinare informazioni sufficienti nel blocco di memoria assegnato per poter deallocarlo in seguito, senza ulteriori input. Spesso, l'allocatore scrive ulteriori informazioni sull'offset negativo dal puntatore restituito. –

risposta

1

Il corto di esso: Con nuova collocazione è l'unico caso in cui in modo esplicito chiamando il distruttore è OK:

baseObj-> ~ Base();

Ma questo sembra stupido perché, con il tuo pool di memoria, stai effettivamente facendo in modo che l'utente mantenga tutta la contabilità ... questo rende la tua classe di memoria non migliore (e probabilmente un po 'peggio) rispetto all'uso di un std :: vector.

non avrei l'utente fare la nuova collocazione stessi ... anzi, se fornendo il proprio pool di memoria, esso dovrebbe essere fatto withing classe 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 
    } 
} 

Onestamente, questo è l'unico modo perché la tua piscina abbia più utilità, allora l'utente finale si limita a creare il proprio std::vector<uint8_t>.

Va notato che questo non fa nulla per mantenere T da allocare qualsiasi altra cosa sul mucchio ...

+0

ok .. probabilmente mi puoi illuminare di più sulla domanda di design http://stackoverflow.com/questions/27375620/generic-memory-pool-how-to-design-issue Non sto ottenendo completamente quello che stai cercando di dire – Adorn