Costruttore di copia

di il
18 risposte

Costruttore di copia

Dato il seguente costruttore di copia:
Libretto& Libretto::operator = (const Libretto& l){
  if (this != &l){
     if (nVoci != l.nVoci){
	    delete [] vett;
	    nVoci = l.nVoci;
	    vett = new riga[nVoci];	
	 }
	 quanteVoci = l.quanteVoci;	
	 for(int i = 0; i < quanteVoci; i++) 
	    vett[i] = l.vett[i];
  }
  return *this;
}
Noto che viene gestito il caso dove il puntatore dell'istanza di classe può essere uguale a quello dell'argomento che è un riferimento della classe ed immagino che quel caso si possa avere se p.e. se nel main facessi un assegnamento del tipo l=l dove l è un oggetto di classe Libretto.
Il valore di ritorno non mi torna, se non sbaglio il valore di ritorno di un assegnamento coincide con quello a destra dell'uguale ma in questo caso non capisco perchè viene ritornato this*, forse non sarebbe stato più logico 'l' ?
Spero di essermi spiegato bene.

18 Risposte

  • Re: Costruttore di copia

    Dato il seguente costruttore di copia:
    Forse intendevi dire l'overload dell'operatore di assegnamento?!
    se non sbaglio il valore di ritorno di un assegnamento coincide con quello a destra dell'uguale
    Se provi a lanciare il seguente codice ti accorgerai che è il contrario:
    int n = 2;
    int m = 3;
    cout << &n << endl;
    cout << &m << endl;
    cout << &(n = m);
  • Re: Costruttore di copia

    Per il punto b tutto chiaro, avevo frainteso.

    Nippolo ha scritto:


    Forse intendevi dire l'overload dell'operatore di assegnamento?!
    Il codice ca cui in realtà mi riferivo era questo, ho sbagliato il copia e incolla:
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    struct riga{ 
      char id[6];
      int voto;
      int cfu;
    };
    
    class Libretto{
      riga* vett;
      int nVoci;
      int quanteVoci;	
      Libretto(const Libretto&);  // mascheramento costr. copia
     
    public:
      Libretto(int);    
      bool aggiungi(const char*, int, int);
      double media()const;
      friend ostream& operator<<(ostream&, const Libretto&);
      // --- SECONDA PARTE ---
      Libretto& operator = (const Libretto&);
      double laurea()const;
      ~Libretto();
    };
    Non trovo alcun codice che definisce cosa fa il costruttore di copia quindi è soltanto dichiarato nell'header.
    Perchè verrà utilizzato questo costruttore di copia mascherato dove non c'e' una riga di codice nel corpo della funzione?
  • Re: Costruttore di copia

    Ma dove prendi i codici che mostri?
  • Re: Costruttore di copia

    shodan ha scritto:


    Ma dove prendi i codici che mostri?
    Perchè? Qual è la percezione?
    Sono testi universitari.
  • Re: Costruttore di copia

    Il codice ca cui in realtà mi riferivo era questo, ho sbagliato il copia e incolla:
    Non capisco... quello che chiedi nel primo post non c'entra nulla con l'ultimo codice che hai postato (mentre calza a pennello con il codice del post iniziale).
    Non trovo alcun codice che definisce cosa fa il costruttore di copia quindi è soltanto dichiarato nell'header.
    Perchè verrà utilizzato questo costruttore di copia mascherato dove non c'e' una riga di codice nel corpo della funzione?
    Non sono sicuro di aver capito bene la domanda... in ogni caso:
    In alcune circostanze si potrebbe non desiderare che un oggetto venga costruito per copia o assegnato. Ma, se non si definiscono overload, il C++ inserirà quelli di default, e se invece li si definiscono, il programma li userà direttamente. Come fare allora? La soluzione è semplice: definire degli overload fittizi e collocarli nella sezione privata della classe; in questo modo gli overload ridefiniti "nasconderanno" quelli di default, ma a loro volta saranno inaccessibili in quanto metodi non pubblici.
  • Re: Costruttore di copia

    La mia personale percezione è che sembra codice preso un po' qua, un po' la.
    Altrimenti nel testo dovrebbe esserci anche la risposta al
    Perchè verrà utilizzato questo costruttore di copia mascherato dove non c'e' una riga di codice nel corpo della funzione?
  • Re: Costruttore di copia

    Ah capisco. Però ho solo riportato L header non il resto. Pensi sia necessario riportare tutto completamente?
  • Re: Costruttore di copia

    Beh, direi proprio di si, altrimenti la tua affermazione
    Non trovo alcun codice che definisce cosa fa il costruttore di copia quindi è soltanto dichiarato nell'header.
    vale per tutte le altre funzioni mostrate nell'header.
  • Re: Costruttore di copia

    #include "compito.h"
    #include <math.h>
    
    Libretto::Libretto(int N){
       nVoci = ( N <= 0) ? 1: N;
       vett = new riga[nVoci];
       quanteVoci = 0;
    }
    
    ostream& operator<<(ostream& os, const Libretto& l){  
      int i;
      for(i = 0; i< l.quanteVoci; i++)
          os << "ESAME" << (i+1) << ": <"<<l.vett[i].id<<","
           <<l.vett[i].voto<<","<<l.vett[i].cfu<< ">" <<endl;
       
      for(; i< l.nVoci; i++)
           os << "ESAME" << (i+1) << ": <>"<<endl;
      return os;
    }
    
    bool Libretto::aggiungi(const char*  id, int voto, int cfu){
      if (quanteVoci == nVoci)
         return false;
     
      if ((voto < 18) || ((voto >30) && (voto != 33)))
         return false;
      if ((cfu != 6) && (cfu != 9) && (cfu != 12))
         return false;  
      if (strlen(id)>5)
         return false;
     
      for (int i = 0; i < quanteVoci; i++)
         if (!strcmp(id,vett[i].id))
            return false;
    
         strcpy(vett[quanteVoci].id,  id);
         vett[quanteVoci].voto = voto;
    	 vett[quanteVoci].cfu = cfu;
    	 quanteVoci++;
     }
    
    double Libretto::media()const{
        double sum = 0;
        if (quanteVoci == 0)
           return sum;
        
        for (int i=0; i<quanteVoci;i++)
             sum+=vett[i].voto;
    	
        double media = sum / quanteVoci;
        return media;
    }
    
    
    // --- SECONDA PARTE ---
      
    Libretto& Libretto::operator = (const Libretto& l){
      if (this != &l){
         if (nVoci != l.nVoci){
    	    delete [] vett;
    	    nVoci = l.nVoci;
    	    vett = new riga[nVoci];	
    	 }
    	 quanteVoci = l.quanteVoci;	
    	 for(int i = 0; i < quanteVoci; i++) 
    	    vett[i] = l.vett[i];
      }
      return *this;
    }
    
    
    double Libretto::laurea()const{
        if (quanteVoci < nVoci) 
    	    return 0;
        double mediaPonderata;
        double sum=0;
        double  cfuSum=0;
        for  (int i=0; i<quanteVoci;i++){
    	    sum += vett[i].voto*vett[i].cfu;
    	    cfuSum += vett[i].cfu;
        }
        mediaPonderata = sum / cfuSum;
        double votoPartenza = (mediaPonderata*3) + 22;
        return votoPartenza;	
    }
    
    Libretto::~Libretto(){
        delete []vett;
    }
  • Re: Costruttore di copia

    Questo invece è il Main
    #include <iostream>
    #include "compito.h"
    using namespace std;
    
    int main(){
      cout<<"---PRIMA PARTE---"<<endl;
      
      cout << "Test del costruttore e dell'operatore di uscita" << endl;
      Libretto l(4);
      cout << l << endl;
      
      cout << "Test della aggiungi" << endl;
      l.aggiungi("I0051",25,9);
      cout << l << endl;
      l.aggiungi("I0054",21,6);
      cout << l << endl;
      
      cout << "Test della media aritmetica:" << endl;
      double media = l.media();
      cout << media << endl<<endl;
      
      
      cout<<"---SECONDA PARTE---"<<endl;
      
      {
        cout << "Test dell'operatore di assegnamento" << endl;
        Libretto l2(3);
    	l2.aggiungi("I0058",30,12);
    	l2 = l;
        cout << l2 << endl;
      }
      
      cout<<"Test del distruttore (l2 e' stato appena distrutto)\n"<<endl;
      
      cout << "Ulteriori test della aggiungi" << endl;
      l.aggiungi("I0062",28,9);
      l.aggiungi("I0051",24,12);
      l.aggiungi("I0067",24,12);
      cout << l << endl;
      
      cout<<"Test calcolo voto di partenza di laurea"<<endl<<"Il voto di partenza e': ";
      double laurea = l.laurea();
      cout<<laurea<<endl<<endl; 
     
      return 0;
      
    }
  • Re: Costruttore di copia

    E se nel main aggiungi la riga
    
    Libretto l1 = l;
    
    che succede?
    (Spero vivamente che tu stia studiando usando un compilatore per provare, se no non vai molto lontano).
  • Re: Costruttore di copia

    Sinceramente non sto capendo a quale domanda si sta cercando di dare risposta!
  • Re: Costruttore di copia

    Nemmeno io. La domanda era sul costruttore di copia perché era mascherato ma siamo in ben altra direzione. Osservazioni sicuramente corrette ma non vedo risposta al mio dubbio.
  • Re: Costruttore di copia

    Io ho risposto a questa:
    Non trovo alcun codice che definisce cosa fa il costruttore di copia quindi è soltanto dichiarato nell'header.
    Perchè verrà utilizzato questo costruttore di copia mascherato dove non c'e' una riga di codice nel corpo della funzione?
    E la risposta è: perchè la classe non deve essere copiabile. Il fatto che manchi la definizione è ininfluente, dato che tale costruttore è privato. Le mie osservazioni volevano farti riflettere su questo e invitarti a provare le cose, (che è il modo migliore di imparare).
    Se tu avessi aggiunto questa riga di codice
    
    Libretto l1 = l;
    

    e provato a compilare, avresti avuto una serie di errori dovuti al fatto che la classe non è copiabile.
    E se non usi un compilatore per studiare, mi spiace, ma stai sbagliando metodo di studio.
Devi accedere o registrarti per scrivere nel forum
18 risposte