2014-08-29 13 views
5

È legale distruggere e costruire un oggetto di classe base in atto per reimpostare la parte dello stato noto alla classe di base?È legale chiamare in modo esplicito destructor class/constructor?

Chiaramente ci sono altri modi per ottenere questo effetto se abbiamo accesso al codice sorgente delle classi. Tuttavia, voglio sapere da una prospettiva linguistica se c'è una ragione specifica per cui questo non è valido.

+0

No. Per iniziare, non vi è alcuna garanzia che '& c' sia uguale all'indirizzo del suo subobject di classe base. –

+0

Punto giusto. Ho aggiunto un cast. –

+0

un metodo 'ricostruire' nella classe base non lo farà? Sembra un problema X-Y. – sp2danny

risposta

8

No, questo non è legale. Non sei autorizzato a sostituire il sottotitolo di base di un oggetto.

C++ 11 3.8/7 specifica che è possibile riutilizzare solo memorizzazione di un oggetto se

l'oggetto originale era un oggetto più derivato (1.8) di tipo T e il nuovo oggetto è un più oggetto derivato di tipo T (ovvero, sono non di base oggetti secondari).

L'oggetto che si sostituisce era un subobject di classe base, non un oggetto di maggior derivazione, ed è quindi vietato.

Se si dovesse sostituire l'intero oggetto (ad esempio, chiamare ~C, quindi creare un nuovo C), sarebbe legale, ma pericoloso. Se il costruttore lanciava, l'oggetto sarebbe distrutto una seconda volta alla fine della sua vita. Ciò darebbe un comportamento indefinito.

+0

Puoi spiegare cosa impedisce l'oggetto di tipo C? Non sto cercando di sostituire o modificare l'oggetto, ma solo di reinizializzare la sua classe di base. –

+0

@ JamesT.Huggett: 'new (...) BaseClass' crea un oggetto di tipo' BaseClass', non 'C'. –

+0

@MikeSeymour Tuttavia, è stato chiamato solo il distruttore della classe base. Capisco che l'OP sta cercando di "reinizializzare" il sottotitolo della classe base senza distruggere una reinizializzazione dell'intero oggetto più derivato. – Angew

2

Il distruttore funzionerà (solo) se è virtuale, altrimenti si avrà un oggetto parzialmente distrutto (che sembra essere quello che si desidera dare i propri commenti, ma non è legale). Il nuovo posizionamento dovrebbe funzionare, ma sono abbastanza sicuro che non è consentito dallo standard (anche se penso che ci siano buone possibilità che sembrerà funzionare). E non sono sicuro del perché lo si vorrebbe, dal momento che l'oggetto era un derivato C ma dopo la costruzione non sarebbe mai più uno C, solo uno .

+0

L'idea è di ripristinare lo stato dell'oggetto base senza toccare i campi aggiunti nella classe derivata. Non sono sicuro di cosa intendi per "essere una C". –

+0

Perché i distruttori virtuali sono rilevanti? Sto chiamando esplicitamente il distruttore che voglio. –

+1

"be a C" si riferisce alla tua 'classe C'. Ciò che stai facendo qui è totalmente sbagliato e non funzionerà. Se il 'BaseClass' dtor è virtuale, verrà chiamato il distruttore' C', e l'oggetto sarà completamente distrutto, anche se la memoria non sarà deallocata perché non hai chiamato 'delete'. Se non è virtuale, forse distruggerete solo i bit di 'BaseClass', ma dubito che sia garantito il funzionamento. Invece di tutto questo, basta creare un semplice metodo 'reset()' sul tuo 'BaseClass'. –

Problemi correlati