Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [C++] mappe like java

    Salve venendo dal java ed approcciandomi a C++, volevo sapere come mai non riesco a definire una mappa di oggetti.
    Inserisco questo codice, ma mi da errori
    codice:
    #include <map>             
    #include <algorithm>        
    #include <iostream>
    #include <string>
    #include "amico.h"
    int main(){
                amico amic ("marco","rossi"); //definisco l'oggetto amic di tipo amico
    
    	    map<string,amico*> amap;          //creo la mappa amap
    	    amap.insert(std::pair<string, amico>("Primo", amic));
                        
                oppure ----> (ma mi da errore lo stesso) amap["Primo"]=amic;
                cout << "Size: " << amap.size() << endl;
    system("pause");
    return 0;    
    }
    --------------------------------------
    //questo invece è il file amico.cpp
    --------------------------------------
    #include "StdAfx.h"
    #include<iostream>
    #include<cstring>
    #include<cassert>
    using namespace std;
    #include "amico.h"
    
    amico::amico( char *first, char *second)
                          {
                          nome= new char[ strlen(first) + 1];
                          assert ( nome != 0);          //termina se non è allocato
                          strcpy( nome, first);
                          cognome=new char[ strlen(second)+1];
                          assert( cognome !=0);         //termina se non è allocato
                          strcpy(cognome,second);
                          }
    void amico::print() 
         {
         cout << nome << " " << cognome;
         }
         amico::~amico(){
                                 delete [] nome;
                                 delete [] cognome;
                                 }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464

    Re: [C++] mappe like java

    Originariamente inviato da MegaAlchimista
    Inserisco questo codice, ma mi da errori
    Se indichi anche gli errori è meglio ... e il file amico.h dov'è ?

    P.S. Prima del main manca uno

    using namespace std;
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Ovvio che non funziona, hai una mappa che contiene puntatori ad amico e cerchi di inserire un oggetto amico.

    Piuttosto, lascia stare i char* e la gestione manuale delle stringhe nella tua classe e usa std::string anche lì, ti risparmierà un sacco di problemi*.



    * la tua classe amico non implementa il costruttore di copie e l'operatore di assegnamento, per cui se un oggetto di tipo amico viene copiato il costruttore di copie di default copierà i puntatori senza assegnare nuova memoria, per cui ti ritroverai con un double free nel distruttore; per questo bisogna sempre ricordarsi della Rule of three, possibilmente implementandoli secondo l'idioma del copy & swap.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da MItaly
    Rule of three
    Sarebbe però da aggiornare inserendoci il move constructor e il move assigment.
    (E al diavolo la retrocompatibilità )
    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.

  5. #5

    Re: Re: [C++] mappe like java

    Originariamente inviato da oregon
    Se indichi anche gli errori è meglio ... e il file amico.h dov'è ?

    P.S. Prima del main manca uno

    using namespace std;
    si scusate:
    using namespace std, l'ho usato, ma ho dimenticato di incollarlo qui.
    Invece il codice del file amico.h non l'avevo inserito per brevità in quanto è banale
    codice:
    class amico {
    public:
             amico( char *, char *); //costruttore
             void print() ; //output nome e cognome
             ~amico(); //decostruttore
    private: 
                char *nome; 
                char *cognome; };
    Originariamente inviato da MItaly
    Ovvio che non funziona, hai una mappa che contiene puntatori ad amico e cerchi di inserire un oggetto amico.

    Piuttosto, lascia stare i char* e la gestione manuale delle stringhe nella tua classe e usa std::string anche lì, ti risparmierà un sacco di problemi*.
    ho provato a modificare il codice così:
    codice:
    map<string,amico> amap;
    amap.insert(std::pair<string, amico>("Primo", amic));
    ma non funziona lo stesso.
    O dici che devo sostituire i tipi nella classe amico?
    Inoltre: cos'è il costruttore di copie? scusa ma non ne ho la più pallida idea

  6. #6
    Originariamente inviato da shodan
    Sarebbe però da aggiornare inserendoci il move constructor e il move assigment.
    (E al diavolo la retrocompatibilità )
    A questo punto diventa la "rule of five".

    Ah, bisognerebbe anche aggiungere lo swap accessibile tramite ADL! (che però è più utile in C++03 che in C++11)

    ... comunque la cosa più saggia a mio avviso è, come per le stringhe, incapsulare le varie risorse in classi che ne gestiscano l'acquisizione/la copia/la distruzione, in modo che poi sia possibile usarli tranquillamente come membri gestiti senza problemi dai "big three" forniti dal compilatore (che chiamano quelli dei membri).
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7

    Re: Re: Re: [C++] mappe like java

    Originariamente inviato da MegaAlchimista
    si scusate:
    using namespace std, l'ho usato, ma ho dimenticato di incollarlo qui.
    Invece il codice del file amico.h non l'avevo inserito per brevità in quanto è banale
    codice:
    class amico {
    public:
             amico( char *, char *); //costruttore
             void print() ; //output nome e cognome
             ~amico(); //decostruttore
    private: 
                char *nome; 
                char *cognome; };

    ho provato a modificare il codice così:
    codice:
    map<string,amico> amap;
    amap.insert(std::pair<string, amico>("Primo", amic));
    ma non funziona lo stesso.
    Non funziona in che senso?
    O dici che devo sostituire i tipi nella classe amico?
    Sì, ti conviene rimpiazzare i char * con delle istanze di std::string, ti eviterai molti mal di testa.
    Inoltre: cos'è il costruttore di copie? scusa ma non ne ho la più pallida idea
    Su che libro di C++ stai studiando? Comunque leggi qui.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8

    risolto

    ok ragazzi grazie ai vostri aiuti sono riuscito a far funzionare questo semplice programmino di test. Ho modificato la classe in modo che lavorasse direttamente con le stringhe, ed ho fatto un'overloading dell'operatore =.

    Metto qui il codice finale e funzionante nel caso dovesse servire a qualcuno in futuro.
    FILE: amico.h

    codice:
    class amico {
    public:
             amico(const std::string&, const std::string&);
             amico& operator=(amico&);
             void print();
             virtual ~amico();
    private:
               std::string nome; std::string cognome; };
    FILE amico.cpp
    codice:
    #include<iostream> #include<string> #include<cassert> using namespace std; #include "amico.h"
    
    amico::amico( const std::string& first, const std::string& second)
       { nome=first; cognome=second;}
    amico& amico::operator=(amico& tizio) {
       nome=tizio.nome;
       cognome=tizio.cognome;
       return *this;}
    void amico::print() { cout << nome << " " << cognome; }
    amico::~amico() { nome.clear(); cognome.clear(); }
    FILE main.cpp
    codice:
    #include <map> #include <algorithm> #include <iostream> #include <string> using namespace std; #include "amico.h"
    
    int main(){
    amico amic ("marco","rossi"); //definisco l'oggetto amic di tipo amico
    amico amic2("cane","pane");
    // amico temp("","");
    
    map<int,amico> amap; //creo la mappa amap
    amap.insert(std::pair<int, amico>(1, amic));
    amap.insert(std::pair<int, amico>(2, amic2));
    cout << "Size: " << amap.size() << endl;
    cout << "\n______________________________________________\n";
    cout << amap.find(1)->first << " "; //stampa il first, ovvero l'intero
    //temp= amap.find(1)->second; temp.print(); //stampa il second, ovvero l'amico
    amap.find(1)->second.print();           //(amap.find(2)->second) è un oggetto di tipo amico
    cout << "\n______________________________________________\n"; 
    
    map<int,amico>::iterator it;
          for(it=amap.begin(); it!=amap.end(); it++)
                   {cout <<"map : " << it->first << " "; it->second.print(); cout << endl;} 
    
    amic2.print(); cout << endl;
    amic2=amic; //test operatore =
    amic2.print(); cout << endl;
    amic.~amico(); //test decostruttore
    amic.print(); cout <<"<- dovrebbe essere uno spazio vuoto" << endl;
    system("pause");
    return 0; }
    Che ne dite, così va bene o nonostante funzioni ci sono ancora errori concettuali?

  9. #9
    Se usi le stringhe C++ (std::string) non ti serve implementare costruttore di copie, operatore di assegnamento e distruttore, dato che quelli forniti di default dal compilatore funzionano senza problemi (richiamano i "big three" dei membri, ovvero di std::string, che si smazzano il lavoro senza che tu ci debba pensare).
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    beh però il distruttore in realtà torna comodo, perchè con un solo comando liberi tutta la memoria dell'oggetto "amico" che desideri, senza dover usare il clear() per ogni suo membro.
    Poi questa è solo una classe scema di prova, quelle che andrò ad implementare avranno ben più di due stringhe

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.