2011-01-25 15 views
6

Ho una classe su cui sto sovraccaricando new e delete (questi recuperano e restituiscono memoria da e verso un pool di memoria). Ciò che mi frustra è che la classe su cui ho sovraccaricato ha ancora il suo distruttore chiamato prima che venga chiamata la funzione di sovraccarico dell'eliminazione. Come posso fermarlo?Arresto del distruttore chiamato

class Message 
{ 
    ~Message() { ... } 

    void* operator new(std::size_t sz) { ... } 
    void operator delete(void* ptr) { ... } 
}; 

EDIT:

Am ragione nel pensare che i membri della classe saranno distrutti, ma la memoria non saranno liberati dai distruttori; la funzione delete possiede questa responsabilità, nel qual caso posso impedire che la memoria venga deallocata?

RISULTATO: Penny caduto che l'assegnazione/deallocazione della memoria e la costruzione/distruzione sono elementi separati. Ora ho distruttori vuoti e sovraccarico nuovo/cancella.

+2

Non so perché questo è frustrante; C++ è molto logico in questo senso. Lascia un distruttore vuoto se non ne hai bisogno per fare qualcosa. –

risposta

6

La distruzione e la disallocazione sono due cose ortogonali, una non dovrebbe inibire l'altra. Cosa faresti con le istanze della tua classe che sono state create nello stack? Non pulire le loro risorse? Stai cercando di rompere un concetto molto utile di RAII.

4

Non penso che tu possa impedire al distruttore di essere chiamato, e non sono sicuro del perché tu voglia. L'oggetto deve essere distrutto prima che la memoria sia liberata - se la superclasse ha assegnato delle risorse, il suo distruttore deve liberarle prima che la memoria dell'oggetto sia liberata.

Modifica dopo la modifica: Sì, i distruttori puliscono tutto ciò che hanno assegnato ma non rilasciano la memoria dell'oggetto. Il metodo delete che stai scrivendo fa quello.

BTW, bel nome. :-)

3

Se siete preoccupati per (a) afferrare la memoria da un pool specifico e (b) il controllo quando i distruttori sono chiamati Una possibilità è placement new:

void* raw = allocate(sizeof(Foo)); // line 1 
Foo* p = new(raw) Foo();   // line 2 

p->~Foo(); // explicitely call destructor 

(codice preso dal link qui sopra per C++ FAQ)

0

Rispondendo alla tua domanda, si chiamano costruttori e distruttori sia che tu sovraccarichi nuovo/cancella o no.

Rispondere a una domanda che non è stata posta, se è una buona soluzione per l'utilizzo degli oggetti con pool di memoria, la risposta è generalmente "no". Quello che vuoi sono le tue classi, che lavorano con il pool di memoria per prendere una classe allocator. Permette molta più flessibilità e in genere non si ha solo una classe, ma molte saranno messe in memoria, quindi non si vuole avere un sovraccarico di massa di tutte le funzioni di nuova/eliminazione. Inoltre, non è insolito avere diversi schemi di allocazione (e quindi allocatori), ma è possibile sovraccaricare nuovo/eliminare solo una volta.

+0

Rispondere alla domanda: come evitare di chiamare un distruttore in C++? Questo può essere fatto solo se si sta facendo uso del posizionamento nuovo per l'allocazione, nel qual caso, come programmatore, si deve assumere la responsabilità di chiamare manualmente il distruttore (come Doug ha detto: p-> ~ Foo :: Foo() ;). Questa è l'unica istanza in linguaggio quando un programmatore deve chiamare manualmente il distruttore. – Viren

Problemi correlati