n° 219
Novembre 2017
Giugno 18, 2018, 06:11:22 *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  


* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: Utilizzo del distruttore di classe  (Letto 1055 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
GPCPP_2018
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 1


Mostra profilo
« inserita:: Gennaio 04, 2018, 04:13:36 »

Buongiorno a tutti,

sto cercando di capire/studiare come gestire la memoria in un programma scritto in C++.
Nel liberare la memoria allocata da un oggetto utilizzando il distruttore di classe tramite istruzione delete mi sorgono diversi dubbi.

esempio:

Codice:
#include <cstdlib>
#include <iostream>

using namespace std;
class prova{
      public:
      int no;
      public:
      prova(){no=4;};
      ~prova(){};
      };
class clase{
      public:
      int valore;
      prova * op;
     
      public:
             clase(){op = new prova[1]; valore = 1000; cout<<"classe ok"<<endl;};
             ~clase(){valore = 500; cout<<"classe terminata"<<endl;};
     
     
     
      };


int main(int argc, char *argv[])
{
    string prosegui;
    clase * pt;
    pt = new clase[1];
    cout<<pt[0].valore<<endl;
    cout<<pt[0].op->no<<endl;
   
 
    delete[] pt;
   
    cout<<pt[0].valore<<endl;
    cout<<pt[0].op->no<<endl;

   
    system("PAUSE");
    return EXIT_SUCCESS;
}



Nel caso precedente non capisco perchè dopo la distruzione dell'oggetto pt mi ritrovo che effettivamente pt[0].valore non ha più il valore assegnato dal costruttore mentre pt[0].op->no rimane invariato...
per distruggere l'oggetto op presente all'interno dell'oggetto pt devo fare il delete di op perchè non basta il delete su pt?









Registrato
AldoBaldo
Newbie
*

Karma: +0/-4
Scollegato Scollegato

Messaggi: 29


Mostra profilo E-mail
« Risposta #1 inserita:: Gennaio 16, 2018, 11:49:36 »

"Disclaimer": NON SONO UN ESPERTO, QUINDI POTREI SCRIVERE DELLE INESATTEZZE.
Qualcuno più pratico mi corregga qualora fosse il caso. Detto questo...



Codice:
#include <cstdlib>
#include <iostream>

using namespace std;

class prova {
    public:
        int no;

        prova() {
            no=4;
        }

        ~prova() {}
};

class clase {
    public:
        int valore;
        prova *op;

        clase() {
            op = new prova[1];  /* quando crei un oggetto di classe clase
                                ** allochi dinamicamente un oggetto di classe
                                ** prova il puntatore al quale viene collocato
                                ** nella proprieta' op */
            valore = 1000;
            cout<<"classe ok"<<endl;
        }

        ~clase() {
            valore = 500; /* questo e' inutile, perche' la proprieta' valore
                          ** dell'oggetto che stai distruggendo non sara' piu'
                          ** disponibile dopo la distruzione */

            delete[] op;  /* quando distruggi l'oggetto di classe clase
                          ** provochi la scomparsa del puntatore conservato
                          ** nella proprieta' op, ma in nessun modo provochi
                          ** la deallocazione automatica della memoria
                          ** dinamica puntata; per liberare quella memoria
                          ** occorre provvedere a una distruzione esplicita
                          ** dell'oggetto puntato da op PRIMA che il puntatore
                          ** op finisca nel "limbo" delle cose distrutte */
                           
            op = NULL;    /* questo e' inutile, perche' la proprieta' op
                          ** dell'oggetto che stai distruggendo non sara' piu'
                          ** disponibile dopo la distruzione, se non per puro
                          ** caso; a scopi dimostrativi, facciamolo lo stesso */

            cout<<"classe terminata"<<endl;
        }
};

int main( int argc, char *argv[] ) {
    clase *pt = new clase[1];
    cout<<pt[0].valore<<endl;
    cout<<pt[0].op->no<<endl;

    delete[] pt;                /* qui hai distrutto l'oggetto creato in memoria
                                ** dinamica, della quale avevi conservato
                                ** l'indirizzo della collocazione in memoria
                                ** nella variabile pt; dal momento della
                                ** distruzione, pt punta a una zona di memoria
                                ** dove non trovi altro che "immondizia", per
                                ** cui pt non dovrebbe piu' essere usato; e'
                                ** pratica comune impostare su NULL un puntatore
                                ** non piu' valido, proprio per essere
                                ** consapevoli del suo stato di puntatore non
                                ** piu' valido */
   
    /* sarebbe bene aggiungere sempre...
   
    pt = NULL;
   
    ...per prudenza; continuiamo senza averlo fatto */
   
    cout<<pt[0].valore<<endl;   /* con questa riga stai mandando in console
                                ** valori in merito ai quali non si sa nulla:
                                ** potrebbero essere qualsiasi cosa, col rischio
                                ** anche (in programmi piu' articolati) di
                                ** combinare dei potenziali "disastri" */

    cout<<pt[0].op->no<<endl;   /* con questa riga, se non e' stato annullato in
                                ** precedenza, stai usando un puntatore ("op")
                                ** che non hai idea di dove punti; casualmente
                                ** POTREBBE anche essere ancora il puntatore
                                ** all'oggetto di classe prova creato
                                ** dall'oggetto di classe clase ormai distrutto,
                                ** ma piu' probabilmente no; a scopi
                                ** dimostrativi ho precedentemente impostato
                                ** pt[0].op->no su NULL, nel distruttore
                                ** CON pt[0].op->no su NULL IMPOSTATO SU NULL,
                                ** QUESTA RIGA MANDA IN PALLA IL PROGRAMMA! */

    system( "PAUSE" );
    return EXIT_SUCCESS;
}
Registrato

Ma cosa vuoi che ne sappia? Io col codice ci gioco, mica ci lavoro!
oregon
Jr. Member
**

Karma: +22/-6
Scollegato Scollegato

Messaggi: 254


Mostra profilo
« Risposta #2 inserita:: Gennaio 17, 2018, 01:05:17 »

op è un puntatore, tu lo hai usato per allocare e tu lo devi usare per distruggere l'oggetto. E' una regola semplice.

E' meglio sempre scrivere

if (op) delete[] op;

Altra storia se nella classe avessi inserito

prova op;
Registrato
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2017 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



powered by Simple Machines