|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
[C++] Quando è necessario usare esplicitamente delete e quando non ce n'è bisogno
E' un po' che devo coprire questa lacuna ma purtroppo il tempo scarseggia e non mi sono ancora documentato.
La mia domanda è semplice: quando devo usare delete esplicitamente? Ad esempio se ho una classe con un puntatore ad un oggetto di un'altra classe, generalmente nel distruttore uso delete (con qualche eccezione). Se ho una funzione con un puntatore di solito non lo faccio ma qui forse sbaglio. Se ho una funzione con una variabile (non puntatore) non lo faccio mai. Avrei bisogno di una documentazione completa a riguardo, avete qualche sito o anche libro in cui possa farmi un'idea completa su questo argomento? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Veramente è semplice ... ad ogni new corrisponde una delete che farai quando quel dato/oggetto non ti serve più.
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
Risposta "moderna": evita di usare puntatori nudi. Fine della storia.
Risposta più "tollerante": - se nella funzione in cui ti trovi hai usato new per creare un oggetto, e alla fine della funzione l'oggetto non ti serve più, usa delete. - se sei in una funzione che prende un puntatore come argomento, in genere non devi usare delete: il puntatore è un riferimento ad un oggetto creato fuori dalla funzione, quindi non spetta a te di doverlo distruggere, visto che dopo la chiamata a tal funzione l'oggetto probabilmente verrà ancora usato. Esempio: Codice:
Color* color = new Color("black");
changeColorToRed(color);
cout << "My color is now: " << *color << endl;
------
void changeColorToRed(Color* c)
{
c->name = "red";
return; // ovviamente non distruggo l'oggetto puntato da c...questa funzione serve solo a modificarlo
}
Codice:
void compute()
{
int* matrix = new int[1000000000]; // alloco 1 miliardo di int
// faccio i conti e stampo a video i risultati
delete[] matrix;
}
int main()
{
for (int i = 0; i < 1000000; ++i)
compute(); // faccio per 1 milione di volte conti su una matrice
}
Tornando alla risposta "moderna": storicamente chi scrive codice ha dimostrato che ricordarsi di liberare manualmente ogni risorsa allocata è praticamente impossibile in programmi di certe dimensioni (cioè in programmi di qualche utilità pratica), senza contare i casi in cui ci sono eccezioni e si salta la parte di codice che libererebbe le risorse, quindi usa unique_ptr<T> e shared_ptr<T>. Sono classi che si assicurano di liberare la memora automaticamente quando non serve più. unique_ptr si usa per oggetti la cui ownership è singola, mentre shared_ptr contiene oggetti a cui si possono riferire più entità. Come avrai intuito è una discussione lunghissima, ma credo di aver riassunto abbastanza i concetti importanti. Per concludere, ora che abbiamo un C++ moderno e possiamo farlo, usa sempre unique_ptr e shared_ptr (così come vector anzichè gli array/i puntatori e string anzichè char*). |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
Grazie. Risposta dettagliatissima come sempre
E sto pure facendo applicazioni da mettere nel portfolio e mostrare alle aziende dunque direi che è ora di metterci le mani. Grazie! |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
Prego. Leggiti anche qualcosa sul concetto più ampio di RAII (resource acquisition is initialization) e come questa tecnica aiuti a rendere superfluo il garbage collector ed estende la soluzione al problema dei puntatori (cioè la eliminazione automatica della memoria allocata) alle risorse di qualsiasi tipo (ad esempio, la chiusura di un file per renderlo disponibile ad altri utilizzatori non devi gestirla manualmente, districandoti tra eccezioni e salti condizionati, ma è garantita dall'oggetto che lo apre).
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:21.




















