Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [C++] Differenza tra Vector e List (STL)

    Ciao a tutti ragazzi!
    vi espongo subito il mio problema, ho la seguente classe:

    class Fattura{
    char *nome;
    char *cognome;
    float iva;
    vector<float> prezzo;
    vector<int> quantita;
    vector<char*> descrizione;
    public:
    Fattura();
    ~Fattura ();
    Fattura (const Fattura &f);
    float importoTotale()const;

    friend bool operator < (const Fattura &c1,const Fattura &c2);

    friend bool operator > (const Fattura &c1,const Fattura &c2);

    void setNome(char *n);
    void setCognome(char *c);
    void setIva(float e);
    friend ostream &operator<<(ostream &out, Fattura &r);
    friend istream &operator>>(istream &in, Fattura &r);
    };

    Di questa classe non ho ben capito come fare il costruttore di copia ( Fattura (const Fattura &f); ) ma solo dei 3 vector: prezzo, quantita e descrizione.
    E inoltre vorrei capire se anzichè vector fossero stati delle list (prezzo, quantita e descrizione) cosa sarebbe cambiato nel costruttore di copia?

    Ho trovato un esempio in cui il costruttore viene fatto in questo modo (adesso considero solo un vector ma è uguale per tutti), ma non so se è giusto:

    prezzo.resize(f.prezzo.size());
    copy(f.prezzo.begin(), f.prezzo.end(), prezzo.begin());

    Un secondo problema mi si pone quando faccio l'istream:
    (anche qui non so se per i vettori si fa così..)

    istream &operator>>(istream &in, Fattura &r)
    {

    char temp[100];
    int app, num;

    in>>temp;
    r.setNome(temp);
    in>>temp;
    r.setCognome(temp);

    in>>app;
    r.setIva(app);

    in>>num;
    r.prezzo.resize(num);
    for(int i=0; i<num; i++){
    in>>r.prezzo[i];
    }
    in>>num;
    r.quantita.resize(num);
    for(int i=0; i<num; i++){
    in>>r.quantita[i];
    }
    in>>num;
    r.descrizione.resize(num);
    for(int i=0; i<num; i++){
    in>>(r.descrizione[i]);
    }

    return in;
    }

    P.S: se fossero invece list come si dovrebbe fare?

    Ah, dimenticavo..non ci sono errori in compilazione.. ma quando lo eseguo, ad es. nel main faccio un semplice caricamento da file.txt mi appare solo la schermata nera vuota.

    Grazie 1000 in anticipo!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381

    Re: [C++] Differenza tra Vector e List (STL)

    Se posti codice, usa i tag CODE o si fa fatica a leggerlo.
    Originariamente inviato da Angelo000
    codice:
     
    prezzo.resize(f.prezzo.size());                                
    copy(f.prezzo.begin(), f.prezzo.end(), prezzo.begin());
    A vedere queste righe il cctor è corretto. Occorre però vedere i char* (nome e cognome).
    Se fossero std::string potresti quasi nemmeno scrivere il cctor.
    Sotto.
    Intanto come assegni in setNome() e setCognome le rispettive variabili?
    Comunque ricorda che std::list non ha operator[] quindi dovresti cambiare il codice perché lavori con la funzione push_back() presente sia in std::vector sia in std::list.
    codice:
    istream &operator>>(istream &in, Fattura &r)
    {
        
        char temp[100];
        int app, num;
        
        in>>temp;
        r.setNome(temp);
        in>>temp;
        r.setCognome(temp);
        
        in>>app;
        r.setIva(app); 
        
        in>>num;
        r.prezzo.resize(num);
        for(int i=0; i<num; i++){
           in>>r.prezzo[i]; 
        }       
        in>>num;
        r.quantita.resize(num);
        for(int i=0; i<num; i++){
           in>>r.quantita[i]; 
        } 
        in>>num;
        r.descrizione.resize(num);
        for(int i=0; i<num; i++){
           in>>(r.descrizione[i]); 
        }     
        
      	return in;
    }
    [/QUOTE]
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Ciao Shodan, Grazie intanto per avermi risposto..

    adesso ti scrivo per intero il costruttore di copia:

    codice:
    Fattura::Fattura(const Fattura &f) 
    { nome=new char[strlen(f.nome)+1];     
       strcpy(nome, f.nome);     
       cognome=new char[strlen(f.cognome)+1];     
       strcpy(cognome, f.cognome);          
       iva=f.iva;               
    prezzo.resize(f.prezzo.size());                                      
    copy(f.prezzo.begin(), f.prezzo.end(), prezzo.begin());
    quantita.resize(f.quantita.size());                                      
    copy(f.quantita.begin(), f.quantita.end(), quantita.begin()); 
    descrizione.resize(f.descrizione.size());                                      
    copy(f.descrizione.begin(), f.descrizione.end(), descrizione.begin());
    }
    Per quanto riguarda i set, li faccio così:

    codice:
    void Fattura::setNome(char *n) 
    { nome=new char[strlen(n)+1];
      strcpy(nome, n); 
    }  
    
    void Fattura::setCognome(char *c)
    { cognome=new char[strlen(c)+1];
       strcpy(cognome, c); }   
    
    void Fattura::setIva(float e) 
    {   iva=e;  }
    Ma quindi se avessi delle List al posto dei Vector il costruttore di copia sarebbe uguale?

  4. #4
    Ok, il costruttore di copia è giusto.. adesso funziona il programma ma c'è sempre qualche problema e credo sia dovuto agli stream perchè se il file input.txt è solo fatto ad es. così:

    mario rossi 20 3 20 2 mouse 20 2 tastiera 13 2 disco

    viene caricato e visualizzato bene sullo schermo, invece se lo faccio così (come dovrebbe essere):

    mario rossi 20 3 20 2 mouse 20 2 tastiera 13 2 disco
    marco bianchi 15 2 150 5 stampante 700 3 pc
    roberto biagi 20 1 300 4 ipod
    biagio antonacci 20 3 20 1 cavo 20 1 software 440 2 servizi
    giuseppe grillo 20 2 8000 1 service 4000 1 catering

    non funziona nulla, mi appare ancora solo la schermata nera..

    Adesso inserisco gli stream, così magari potete vedere se c'è qualcosa ke non va:



    codice:
    ostream &operator<<(ostream &out, Fattura &r) 
    { out<<r.nome<<"  "<<r.cognome<<"  "<<r.iva<<" ";     
    for(int i=0; i<(int)r.prezzo.size(); i++)     
    { out<<r.prezzo[i]<<" ";  
    cout<<endl;     }                            
    for(int j=0; j<(int)r.quantita.size(); j++)
    { out<<r.quantita[j]<<" "; 
     cout<<endl;     }      
    for(int z=0; z<(int)r.descrizione.size(); z++)
    {  out<<(r.descrizione[z])<<" "; 
    cout<<endl; }              
    return out; }
    L'istream l'ho modificato così e va bene sia se ho Vector che List:

    codice:
    istream &operator>>(istream &in, Fattura &r) 
    {  char temp[100];     
       int app, num;          
       in>>temp;     
       r.setNome(temp);    
       in>>temp;    
       r.setCognome(temp);         
       in>>app;     
       r.setIva(app);           
       vector<float>::iterator p=r.prezzo.begin();  
        while(p!=r.prezzo.end())      
    {  float app; 
        in>>app;          
      r.prezzo.push_back(app);
          }          
    vector<int>::iterator s=r.quantita.begin();
    while(s!=r.quantita.end())     
     {  int app;         
         in>>app;                 
         r.quantita.push_back(app);       
    }      
    vector<char*>::iterator t=r.descrizione.begin();
    while(t!=r.descrizione.end()) 
    {  char* app;         
        in>>app;                 
        r.descrizione.push_back(app);        
    }   	return in; 
    }
    E infine gli stream di In e Out per la List:



    codice:
    ostream &operator<<(ostream &o, list<Fattura> &l) 
    {   list<Fattura>::iterator p = l.begin();     
    while(p != l.end())
    {   o << *p<<" ";        
    p++;      }      
    cout<<endl;      
    return o; }  
    
    istream &operator>>(istream &i, list<Fattura> &l) 
    { while(!i.eof())        
     { Fattura app;       
     i >> app;         
    if(!i.eof())        
    {  l.push_back(app);   
         }         
     }    return i; 
    }
    P.S: nel main non faccio altro che questo:
    codice:
    int main(int argc, char** argv) 
    {   list<Fattura> l1;      
        ifstream in;   
        in.open("input.txt", ios::in);   
        in>>l1;   
        in.close();    
        cout<<l1;                                                  
    system("PAUSE");	     
    return (EXIT_SUCCESS);
    }
    Ragazzi grazie mille cmq per l'attenzione e il tempo che mi dedicate..

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Calma. Ci sono ancora ancora errori sia nel cctor sia nell'operatore di inserimento.
    Questo puoi semplificarlo così:
    codice:
    istream &operator>>(istream &i, list<Fattura> &l) 
    { 
       while(i.good()) { 
          Fattura app;       
          i >> app;
          l.push_back(app);
       }
       return i;         
    }
    Questo invece ha un errore grave.
    codice:
    istream &operator>>(istream &in, Fattura &r) 
    { 
       ...
    vector<char*>::iterator t=r.descrizione.begin();
    while(t!=r.descrizione.end()) 
    { 
        char* app; // qui rischi un crash se non allochi memoria per la variabile.        
        in>>app;                 
        r.descrizione.push_back(app);        
    }   	return in; 
    }
    Costruttore copia.
    codice:
    Fattura::Fattura(const Fattura &f) 
    { 
    ...
    descrizione.resize(f.descrizione.size());                                      
    copy(f.descrizione.begin(), f.descrizione.end(), descrizione.begin());
    }
    Questa parte è errata. Il vector contiene dei pointer quindi servono altri passaggi per non avere problemi quando deciderai di liberare la memoria per i char* di descrizione.
    codice:
    Fattura::Fattura(const Fattura &f) 
    { 
    ...
    descrizione.resize(f.descrizione.size()); // questo si deve togliere.                                      
    vector<char*>::iterator t=f.descrizione.begin();
    while(t!=f.descrizione.end()) {
        int len = strlen(*it);
        char* tmp = new char[len];
        copy(*it,( (*it)+len), tmp);
        descrizione.push_back(tmp);
    }
    In ogni caso sia vector sialist sono intelligenti e non serve fare tutta quella trafila per copiarli. Puoi usare semplicemente uno di questi due passaggi:
    codice:
    Fattura::Fattura(const Fattura &f) 
    { nome=new char[strlen(f.nome)+1];     
       strcpy(nome, f.nome);     
       cognome=new char[strlen(f.cognome)+1];     
       strcpy(cognome, f.cognome);          
       iva=f.iva;               
       prezzo= f.prezzo;                                      
       quantita=f.quantita;                                      
    
       vector<char*>::iterator t=f.descrizione.begin();
       while(t!=f.descrizione.end()) {
          int len = strlen(*it);
          char* tmp = new char[len];
          copy(*it,( (*it)+len), tmp);
          descrizione.push_back(tmp);
       } 
    }
    O meglio ancora:
    codice:
    Fattura::Fattura(const Fattura &f) : prezzo(f.prezzo), quantita(f.quantità) {
       nome=new char[strlen(f.nome)+1];     
       strcpy(nome, f.nome);     
       cognome=new char[strlen(f.cognome)+1];     
       strcpy(cognome, f.cognome);          
       iva=f.iva;               
    
       vector<char*>::iterator t=f.descrizione.begin();
       while(t!=f.descrizione.end()) {
          int len = strlen(*it);
          char* tmp = new char[len];
          strcpy(tmp,*it);
          descrizione.push_back(tmp);
       } 
    }
    Comunque ti sconsiglio di usare char* come fossero stringhe. Usa la std::string piuttosto.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  6. #6
    Scusami Shodan ma perchè nel costruttore di copia i due vettori prezzo e quantità li fai semplicemente così?

    codice:
    prezzo= f.prezzo;                                          
    quantita=f.quantita;
    non richiedono un ciclo?

    Comunque i char* ce li fa usare il prof in questo modo..

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Angelo000
    Scusami Shodan ma perchè nel costruttore di copia i due vettori prezzo e quantità li fai semplicemente così?

    codice:
    prezzo= f.prezzo;                                          
    quantita=f.quantita;
    non richiedono un ciclo?
    No, vector e list sono classi "furbe" che hanno operatore di assegnamento e costruttore di copia incorporato, i quali si arrangiano a copiarsi i valori senza doversi inventare cicli e cose strane. Ovviamente devono essere della stessa classe.
    Se hai due vector puoi semplicemente assegnarli, se hai un vector e una lista devi fare come avevi fatto prima.
    Comunque i char* ce li fa usare il prof in questo modo..
    Pessima idea. Professore bocciato.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  8. #8
    Shodan, anche se il programma ancora non funziona bene (perchè non mi ci sono dedicato molto finora), ti ringrazio per i tuoi suggerimenti ed il tempo che mi dedichi.

    Vorrei chiederti ancora una cosa, i due vettori prezzo e quantita mi hai detto che posso farli così nel costruttore di copia:

    codice:
    prezzo= f.prezzo;                                           
    quantita=f.quantita;
    invece il vettore di char* no? e se no, perchè?

    E senti, visto che nel costruttore di copia si può evitare di far cicli per Vector e List, si possono evitare anche quando si scrive l'ostream? cioè qui:

    codice:
    ostream &operator<<(ostream &out, Fattura &r)  
    { out<<r.nome<<"  "<<r.cognome<<"  "<<r.iva<<" ";      
    for(int i=0; i<(int)r.prezzo.size(); i++)      
    { out<<r.prezzo[i]<<" ";   cout<<endl;     } 
    for(int j=0; j<(int)r.quantita.size(); j++) 
    { out<<r.quantita[j]<<" ";   cout<<endl;     }
    for(int z=0; z<(int)r.descrizione.size(); z++) 
    {  out<<(r.descrizione[z])<<" ";  cout<<endl; }
    return out; }
    Grazie ancora cmq..

    P.S: si, il prof è proprio matto..

  9. #9
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Angelo000
    invece il vettore di char* no? e se no, perchè?
    Perché non è una classe. char* è un puntatore e come tutti i puntatori è stupido.
    Se non hai avuto problemi fino a ora è perché non hai mai deallocato il contenuto del vector<char*>. Il problema nasce quando andrai a deallocare il char* visto che ti ritroverai due vector<char*> con gli elementi (che sono puntatori) che punteranno alla stessa locazione di memoria. Visto che non è possibile deallocare due volte lo stesso puntatore, la prima volta tutto fila liscio, la seconda avrai un crash.

    Detto in parole povere stai facendo qualcosa del genere:
    codice:
        char* buffer=new char[16];
        char* tmp = buffer;
        delete[] buffer;
        delete[] tmp;
    Ricorda che il vector per assegnare gli elementi interni utilizza l'operatore= ma di suo non sa se quello che contiene è un puntatore o no. Deve essere il programmatore a gestire i vari elementi interni. Con la std::string non sarebbe stato necessario ad esempio perché anche lei ha operatore di assegnamento e cctor.

    E senti, visto che nel costruttore di copia si può evitare di far cicli per Vector e List, si possono evitare anche quando si scrive l'ostream?
    Risposta breve: si.
    Risposta corretta: si può fare mascherando il ciclo.
    codice:
    copy(r.quantita.begin(),r.quantita.end(),ostream_iterator<int>(cout));
    copy effettua un ciclo tra gli elementi e li manda a cout, il tutto con una riga di codice.
    Nota che usando iteratori, quantita può essere anche una list e il codice non cambia.
    Con:
    codice:
    copy(r.quantita.begin(),r.quantita.end(),ostream_iterator<int>(cout,'\n')); // o "\n" non ricordo.
    vai a capo ad ogni iterazione.
    P.S: si, il prof è proprio matto..
    O poco aggiornato
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.