Contenimento lasco e costruttori di copia

di il
4 risposte

Contenimento lasco e costruttori di copia

Ciao a tutti, in pratica ho la classe "utente" che contiene "data" con un contenimento lasco, utente ha un costruttore di copia ma quando lo uso mi risulta che le "date" di "u" e "u2" (istanze della classe utente) non sono separate: hanno stesso indirizzo e le modifiche su "u.d" vengono effettuate anche su "u2.d".
Se al posto del costruttore di copia uso quello commentato il programma mi da errore: "segmentation faul"
Qualcuno sa come aiutarmi?

file data
using namespace std;
class Data{
    friend ostream& operator<<(ostream &,const Data&);
    private: 
         int mese;
         int anno;
    public:
       Data(const int m,const int a):mese(m),anno(a){}
       ostream& stampa(ostream& out)const{
           out<<mese<<" "<<anno;
           return out;
       }
};

ostream& operator<<(ostream& out,const Data &d){return d.stampa(out);}
file utente

#include "data.h"
using namespace std;
class Utente{
    friend ostream& operator<<(ostream &,const Utente&);
    private: 
         Data *d;
    public:
       Utente():d(NULL){}                    //costruttore vuoto
       Utente(Data *di):d(di){}               //costruttore
       Utente(const Utente &u):d(u.d){}        //costruttore di copia
       /*Utente(const Utente &u){
          *d=*(u.d); 
       } */
       void setData(const Data &di){*d=di;}
};

ostream& operator<<(ostream& out,const Utente &u){out<<*(u.d)<<' '<<u.d; return out;}
file main
#include <iostream>
#include "Utente.h"
using namespace std;

int main(){
   Data d(1,2000);
   Data d2(2,222);
   
   Utente u(&d);
   Utente u2(u);
   
   cout<<u<<'\n'<<u2<<'\n';
   
   u.setData(d2);
   
   cout<<u<<'\n'<<u2<<'\n';
   
}

4 Risposte

  • Re: Contenimento lasco e costruttori di copia

    RAGIONA:
    1) hai "d"
    2) hai "u" che punta a "d" (che si trova nello stack e questo e FONTE DI ROGNE INESAURIBILI)
    3) hai "u2" che PUNTA sempre a "d"

    E' OVVIO che quando modifichi "u" ti ritrovi con "u2" modificato, perch'e ENTRAMBI fanno riferimento allo STESSO "d".

    Ma c'e' un'azione ancora piu' miracolosa: SE modifichi "d", MIRACOLOSAMENTE ti ritrovi modificati ANCHE "u" e "u2"
  • Re: Contenimento lasco e costruttori di copia

    Grazie della risposta
    ma come faccio a fare in modo che "u" e "u2" abbiano "d" diversi tramite un costruttore di copia?
    Perché con
    Utente(const Utente &u):d(u.d){}
    si copiano gli indirizzi e quindi hanno stessa locazione nella memoria dunque sono fra loro dipendenti

    Mentre se volessi copiare solo il valore farei *d=*u.d ma questa istruzione mi da errore, quindi come fare?
  • Re: Contenimento lasco e costruttori di copia

    Non puoi perché d dell'oggetto appena creato non punta ad un'area di memoria valida (probabilmente è un puntatore nullo). Al limite potresti definire l'operatore = in cui metti quell'istruzione, dopodiché
    inizializzare i due utenti con d e d2 e infine copiarli.

    Le soluzioni migliori (una delle due) sono invece:
    1) Allocare il campo data nell'heap con una new, invece di prenderlo da una variabile locale del main, in modo che nel momento in cui costruisce l'oggetto Utente gli riserva la memoria per la data, che viene fatta puntare da d.
    2) Non usare puntatori, ma una semplice variabile di tipo Data all'interno di Utente.
  • Re: Contenimento lasco e costruttori di copia

    Grazie mille
Devi accedere o registrarti per scrivere nel forum
4 risposte