Salve a tutti. Studio da qualche mese il C++ e al momento avrei dei dubbi che google non e' riuscito ancora a togliermi.
Vi posto il sorgente (funzionante e scritto da me) riguardo le liste linkate che ho creato per capire come funzionano le classi e nello specifico il rapporto che lega i costruttori con le funzioni di allocazione new/delete.
Leggendo in giro per internet ho notato che in molti non colgono l'importanza dei costruttori dei distruttori.codice:#include<stdlib.h> #include<stdio.h> #include <iostream.h> class BOX { public: int* valore; BOX* p_next; BOX() { cout<<"Costruzione BOX"<<endl; valore = new int(-1); cout<<"Fine Costruzione BOX"<<endl; }; ~BOX() { cout<<"Distruzione BOX"<<endl; delete valore; cout<<"Fine Distruzione BOX"<<endl; }; }; class LISTA { public: int* n_valori; //contatore di quanti valori sono stati inseriti BOX* start; //punta al primo valore della lista BOX* temp; //scatola aggiunta volta per volta LISTA() { cout<<"Costruzione LISTA"<<endl; n_valori = new int(0); temp = new BOX; cout<<"Fine Costruzione LISTA"<<endl; }; ~LISTA() { cout<<"Distruzione LISTA"<<endl; delete n_valori; delete temp; cout<<"Fine Distruzione LISTA"<<endl; }; }; int main (void) { int *scelta; LISTA lista; scelta= new int; lista.start = lista.temp; //il puntatore START conserva l'indirizzo di memoria della prima box cout <<"Inserire quanti numeri si vogliono inserire: "<<endl; cin >> *scelta; // MEMORIZZAZIONE BOXs for ((*lista.n_valori)=0; (*lista.n_valori)<*scelta; (*lista.n_valori)++) { cout<<"Inserire il "<<(*lista.n_valori)+1<<" valore: "; cin>> *lista.temp->valore; cout<<endl; lista.temp->p_next = new BOX; lista.temp=lista.temp->p_next; } delete scelta; // dealloco scelta perche' non mi interessa conservarla // FINE MEMORIZZAZIONE BOXs scelta= new int(0); // utilizzo il puntatore scelta allocando una grandezza int per utilizzarlo nel ciclo for lista.temp = lista.start; //punto all'inizio della lista creata for (*scelta=0; *scelta<*lista.n_valori; (*scelta)++) // ciclo for che stampa il valore e segue il puntatore { cout<<(*scelta)+1<<" valore: "<<*lista.temp->valore<<endl; lista.temp=lista.temp->p_next; } delete scelta; //dealloco scelta delete lista.temp->p_next; // questo delete mi richiama il distruttore BOX...e fin qui...posso anche capirlo delete lista.temp; // mi aspetto che venga chiamato il distruttore LISTA...e invece e' sempre BOX... system("PAUSE");
Sostanzialmente ho capito che i costruttori servono ad inizializzare le variabili e ad allocare memoria. Ma perche' i distruttori? (so che dealloca ma...)
nel distruttore della classe LISTA per esempio io ho
e se volessi soltanto deallocare n_valori per esempio e non temp? non potrei farlo perche' quando uso il delete di un puntatore viene richiamato il distruttore corrispondente andando a cancellarmi anche temp!codice:n_valori = new int(0); temp = new BOX;
che differenza c'e' tra dichiarare i costruttori e i distruttori come ho fatto io e, invece, inizializzare le variabili nelle dichiarazioni e allocarle/deallocarle all'interno del main...??
e' come se mi sfuggisse la vera importanza dei costr/distruttori!
Altra cosa:
ogni volta che immetto un nuovo valore viene definita una nuova BOX e quindi vengono eseguiti i rispettivi costruttori (faccio stampare a monitor delle stringhe per capirlo meglio), ma quando chiamo il distruttore...viene eseguito una volta sola... va bene cosi'?
1 distruttore basta per lo stesso costruttore chiamato piu' volte?
qualcuno mi sa dire perche' il distruttore di LISTA non viene mai chiamato anche se scrivo delete lista.temp?
ultima domanda (per ora altrimenti il messaggio diventa troppo dispersivo):
[B]nel momento in cui imparo a creare delle variabili allocando dinamicamente dei puntatori (che sia malloc o new non importa) non mi conviene piu' dichiarare delle variabili normalmente??
cioe' quando non e' consigliabile creare variabili "allocate con puntatori" in favore di quelle tradizionali?
se fossi un programmatore dichiarerei tutte la variabili "dinamicamente" in modo tale da avere sempre la possibilita' di deallocarle e risparmiare memoria...o no? o c'e' un momento in cui il classico int valore è meglio di int* valore; valore=new int.
Spero di non aver esagerato e vi ringrazio per la risposta!
:berto: