2012-03-31 15 views
8

Il distruttore predefinito nelle classi C++ elimina automaticamente i membri che non sono allocati esplicitamente nel codice? Ad esempio:quanto fa il distruttore predefinito

class C { 
    public: 
    C() {} 
    int arr[100]; 
}; 

int main(void) { 
    C* myC = new C(); 
    delete myC; 
    return 0; 
} 

Elimina myC deallocare arr myC automaticamente? O devo scrivere il distruttore di C per farlo in modo esplicito?

+2

http://www.parashift.com/c++-faq-lite/dtors.html – Anycorn

+0

elimina automaticamente l'array. – JosephH

risposta

5

Il costruttore (in assenza di qualsiasi elenco iniziatore-Ctor) chiama il costruttore predefinito per ciascun sottooggetto.

Dato che non ci sono classi base e le variabili membro sono tipi primitivi, non farà nulla.

Uguale al distruttore. Il tuo è implicitamente generato dal compilatore poiché non ne hai dichiarato uno, e chiamerà il distruttore per ogni sotto-oggetto. Ancora una volta è banale perché il tuo solo suboject è un aggregato di primitive.

Ora, tutta la memoria della classe verrà liberata quando la si elimina. Poiché la matrice è incorporata all'interno della classe, fa parte della stessa area di memoria e verrà liberata allo stesso tempo.

+0

@Mark: non esiste una distinzione "predefinita" per i distruttori, poiché non possono essere sovraccaricati. –

+0

@Mark: nessun problema. –

+0

Con "subobject" intendi "membro dati", sicuramente? –

5

Il distruttore (predefinito) implicitamente definito chiamerà il distruttore per ciascun membro. Nel caso di un array membro, chiamerà il distruttore per ogni elemento dell'array.

Si noti che i puntatori non hanno distruttori; è necessario eliminarli manualmente. Non hai questo problema nell'esempio fornito, ma è qualcosa di cui essere a conoscenza.

+1

I puntatori hanno tipo distruttori [(vedi qui)] (http://ideone.com/97iUx), anche se ovviamente non eliminano ciò a cui puntano. – Pubby

+0

wait ... tu dici che i puntatori non hanno distruttori, ma pensavo che delete prendesse solo un puntatore. stai dicendo che il distruttore predefinito chiamerebbe delete ogni 100 pollici dell'array? – Robz

+0

@Robz, No - Sto dicendo che il distruttore implicito * non * chiama delete, devi farlo tu stesso in un distruttore esplicito se hai dei puntatori grezzi come membri. –

5

Se la classe/struttura contiene un puntatore e si assegna in modo esplicito qualcosa a cui fare riferimento il puntatore, in genere è necessario scrivere un valore delete corrispondente nel gestore. I membri direttamente incorporati nella classe/struct verranno creati e distrutti automaticamente.

class X { 
    int x; 
    int *y; 
public: 
    X() : y(new int) {} 
    ~X() : { delete y; }  
}; 

Qui X :: x verrà creato/distrutto automaticamente. X: y (o, per essere tecnicamente corretto, ciò che X: y indica) non lo assegneremo al ctor e lo distruggeremo nel dtor.

+0

'X :: y' viene distrutto automaticamente. È' * (X :: y) 'che potrebbe fuoriuscire se non fosse per il distruttore. (E il tuo campione infrange la Regola di tre/Quattro/Cinque) –

+0

@BenVoigt: Sì, la domanda riguardava cosa fa il distruttore, non come scrivere una classe che gestisca correttamente la proprietà remota. –

0

Tutto ciò che si chiama nuovo per deve avere una cancellazione corrispondente. Se non hai chiamato new per creare un'istanza di qualcosa allora non devi chiamare delete.

+0

IMHO, si dovrebbe raramente "cancellare" qualcosa nel codice dell'applicazione. membro-di semantica per tutti i membri, tale che la distruzione automatica lo fa il trucco. In caso contrario, i puntatori intelligenti sono spesso un'alternativa migliore ai puntatori manuali e alla funzione "cancella". – Rawler

-1

Non è necessario scrivere un distruttore. La classe C++ ha il distruttore predefinito per eliminare l'oggetto dopo "return 0" per riciclare la memoria.

Problemi correlati