Sì, le variabili automatiche verranno distrutte alla fine del blocco di codice che la racchiude. Ma continua a leggere.
Il titolo della domanda chiede se verrà chiamato un distruttore quando la variabile esce dall'ambito. Presumibilmente, ciò che intendevi chiedere era:
il distruttore di Foo sarà chiamato alla fine di main()?
Dato il codice che hai fornito, la risposta a questa domanda è no poiché l'oggetto Foo ha una durata di storage dinamica, come vedremo tra breve.
Nota qui ciò che la variabile automatica è:
Foo* leedle = new Foo();
Qui, leedle
è la variabile automatico che sarà distrutto. leedle
è solo un puntatore. La cosa che leedle
punta a non corrisponde a ha una durata di archiviazione automatica e non verrà distrutta. Quindi, se si esegue questa operazione:
void DoIt()
{
Foo* leedle = new leedle;
}
Hai perdite la memoria allocata da new leedle
.
È mustdelete
tutto ciò che è stato assegnato con new
:
void DoIt()
{
Foo* leedle = new leedle;
delete leedle;
}
Ciò è reso molto più semplice e più robusto, utilizzando puntatori intelligenti. In C++ 03:
void DoIt()
{
std::auto_ptr <Foo> leedle (new Foo);
}
o C++ 11:
void DoIt()
{
std::unique_ptr <Foo> leedle = std::make_unique <Foo>();
}
puntatori intelligenti sono utilizzati come variabili automatiche, come sopra, e quando escono di portata e sono distrutte, automaticamente (nel distruttore) delete
l'oggetto puntato. Quindi, in entrambi i casi sopra, non c'è perdita di memoria.
Proviamo a chiarire un po 'di linguaggio qui. In C++, le variabili hanno una durata di archiviazione. In C++ 03 ci sono 3 durate di memorizzazione:
1: automatico: Una variabile con durata di archiviazione automatica verrà distrutta alla fine del blocco di codice che la racchiude.
Considerate:
void Foo()
{
bool b = true;
{
int n = 42;
} // LINE 1
double d = 3.14;
} // LINE 2
In questo esempio, tutte le variabili hanno durata memorizzazione automatica. Sia b
e d
verranno distrutti a LINE 2. n
verranno distrutti a LINE 1.
2: statico: Una variabile con durata di conservazione statica sarà assegnata prima che il programma inizia, e distrutta quando il programma termina.
3: dinamica: Una variabile con durata di conservazione dinamica verrà allocata quando si assegnano utilizzando funzioni di allocazione di memoria dinamica (ad esempio, new
) e verranno distrutti quando distruggere utilizzando funzioni di allocazione di memoria dinamica (ad esempio, delete
).
Nel mio esempio originale sopra:
void DoIt()
{
Foo* leedle = new leedle;
}
leedle
è una variabile con durata di conservazione automatica e verranno distrutti alla brace fine. La cosa a cui punta leedle
ha durata di archiviazione dinamica e non viene distrutta nel codice sopra. È necessario chiamare delete
per deallocarlo.
C++ 11 aggiunge anche una quarta durata di conservazione:
4: filetto: variabili con durata di conservazione filo sono assegnati quando inizia il filo e deallocate quando le estremità del filo.
No, è necessario chiamare 'delete leedle'. – juanchopanza
Puoi fare una risposta e approfondire perché? – Tux
Sì alla domanda nel titolo, No alla domanda nel corpo. Devi cancellare manualmente tutto ciò che è nuovo. Se si usa 'new' nel costruttore (a meno che non siano generate eccezioni) è possibile chiamare' delete' nel distruttore e pulirà la memoria per voi. – Rapptz