Passare stream a funzione

di il
30 risposte

Passare stream a funzione

Salve ragazzi,
mi spiego meglio sto facendo un progetto e dato che devo creare un oggetto prendendo in input da un utente alcune informazioni vorrei sapere se è possibile fare una cosa del genere (posto il codice) :

Ho i miei metodi set dichiarati,quindi io vorrei fare una cosa del genere

void Archivio::immissione(){
			Citta temp;
			cout<<"Hai scelto di inserire una nuova citta',compila i seguenti campi:"<<endl;
			cout<<"Inserisci nome della città"<<endl
			temp.setcitta(qui vorrei passare direttamente lo stream)
                        elencocitta.push_back(temp);
	}
Vorrei passare direttamente lo stream di input senza dichiarare una variabile per poi passarla !! Si può??
Altra piccola cosa, se voi ci fate caso ho dovuto dichiarare una variabile temp per poi pussharla nel vector , posso fare lo stesso senza dichiarare la variabile temp quindi pusshare l'oggetto prima nel vector e lavorare con gli indici del vector?
Non so se mi sono fatto capire,
spero nelle vostre risposte
Grazie
Luigi351

30 Risposte

  • Re: Passare stream a funzione

    Devi includere l'overload dell'operatore >> nella tua classe cittá cosí puoi eseguire in un solo colpo l'inserimento col comando cin >> temp;
    nel'altro caso se non vuoi copie temporanee devi creare un vettore di puntarori a Citta o magari un vettore di std::shared_ptr< Citta >
  • Re: Passare stream a funzione

    Si quella dell'overloading mi era venuta in mente come idea! potresti spiegarmi cosa intendi con questo :
    std::shared_ptr< Citta >
    Grazie!
  • Re: Passare stream a funzione

    Non sono al computer ma una cosa del genere potrebbe fare al caso tuo
    
    std::vector<shared_ptr<Citta>> v;
    std::shared_ptr tmp = make_shared<Citta>();
    cin >> *tmp;
    v.push_back(tmp);
    
    in questo caso il vettore tiene solo il puntatore all'oggetto Citta. Essendo sto puntatore di tipo shared_ptr (ma potresti usare anche unique_ptr dipende dal design) la copia si riduce alla copia di un puntatore e quando il vettore si distrugge lui chiede ad ogni elemento di chiamare il destructor e quindi nessun memory leak. Provalo.
  • Re: Passare stream a funzione

    No, unique_ptr non funziona con i container standard visto che per design non ha costruttore di copia e operatore di assegnamento.
    shared_ptr è ottimale. Al limite cosiglierei:
    
    v.push_back(std::move(tmp));
    
    per evitare una chiamata inutile al reference counter interno.
  • Re: Passare stream a funzione

    Thnx shodan, sei sempre una miniera in materia STL. Grazie
    Ma in Microsoft hanno implementato l'op di assegnamento?
    http://msdn.microsoft.com/en-us/library/ee410580.asp

    Premetto che non ho mai usato unique_ptr in un contesto avanzato solo test.
  • Re: Passare stream a funzione

    Quanta esperienza che c'è su questo forum!! Complimenti comunque io ho risolto così:
    
    void Citta::setcitta(istream& c){ c>>nome_citta; } 
    ...
    temp.setcitta(cin);
    
    Dite che è una soluzione ottimale??

    Per quanto riguarda std::shared_ptr< Citta > non l'ho mai usato e il mio prof non l'ha fatto nemmeno a lezione,quindi per ora preferisco l'oggetto temporaneo anche perchè devo consegnare a breve il progetto e non ho tempo di studiarmi per bene questo approccio.

    Ora ho un dubbio ... volendo fare l'overload dell'operatore >> mi troverei in difficoltà dato che devo usare i setter perchè non posso modificare direttamente gli attributi poichè mi trovo in un'altra classe che ha come attributo Citta temp. voi che dite?
    Grazie ancora!
  • Re: Passare stream a funzione

    
    temp.setcitta(cin);
    
    Così non mi piace. L'immediato sarebbe quello di vedere una string come nome non un istream. Così mi salta all'occhio male. Ma devi per forza usare il setter?
  • Re: Passare stream a funzione

    skynet ha scritto:


    thnx shodan, sei sempre una miniera in materia STL. Grazie
    Ma in Microsoft hanno implementato l'op di assegnamento?
    http://msdn.microsoft.com/en-us/library/ee410580.asp
    No. Se noti c'è il doppio && segno che è move semantics.
    
    
    std::unique_ptr<T> a(new T);
    
    std::unique_ptr<T> b = a; // errore;
    std::unique_ptr<T> c = std::move(a); // ok;
    
    std::unique_ptr<T> d;
    d = a; // errore;
    d = std::move(a); // ok
    
    
    Premetto che non ho mai usato unique_ptr in un contesto avanzato solo test.
    Nelle intenzioni dello standard, lo unique_ptr è lo smart pointer principale. Avendo una semantica di possesso esclusivo è utile quando vuoi avere una classe non copiabile senza dover rendere privati il costruttore di copia e l'operatore di assegnamento (che alla fine servono solo per i puntatori raw), ma è solo un esempio.
    
    class Test {
        unique_ptr<Q> mq;
        public:
            Test() {} 
    };
    
    No costruttore di copia, no operatore di assegnamento, no distruttore.

    Per quel che mi riguarda, uso gli unique_ptr praticamente sempre. Almeno mi evito la gestione manuale dei raw pointer. La cosa notevole è che sia lo unique_ptr (a livello di parametro template) sia lo shared_ptr consentono di specificare la funzione di cancellazione del puntatore interno (che di default è la delete).
    Insomma, per come la vedo io, una volta che inizi a usarli non ne fai più a meno.
  • Re: Passare stream a funzione

    Potresti suggerirmi una soluzione che mi faccia eliminare i setter?
  • Re: Passare stream a funzione

    Infatti io uso shared_ptr da per tutto come da esempio. gli unique no perche cercho di non avere dei rawPtr. Ma se servono iniziero anch'io. ne apro un thread che voglio chiederti qualcos'altro. Intanto grazie

    @shodan
    Cancelato la domanda nel nuovo thread perche stavo sparando caxxate.
  • Re: Passare stream a funzione

    luigi351 ha scritto:


    Potresti suggerirmi una soluzione che mi faccia eliminare i setter?
    Si
    
    class Citta {
     string nome;
    public:
      friend istream &operator>>(istream &stream, inventory &ob);
    };
    
    istream &operator>>(istream &stream, Citta &ob)
    {
      cout << "Inserisci nome citta: ";
      stream >> ob.nome;
      return stream;
    }
    
    utilizzo:
    
    Citta tmp;
    cin >> tmp;
    
    
  • Re: Passare stream a funzione

    Piccolo inghippo,sul progetto che mi è stato consegnato è scritto espressamente "vietato usare dichiarazioni friend" Altri consigli? Grazie per il tuo aiuto!
  • Re: Passare stream a funzione

    Allora usi il setter (ma con una stringa) e lascia stare l'overload per che l'istream deve divewntare friend per scrivere su membri privati.
  • Re: Passare stream a funzione

    
    class Citta{
    	private:
    		string nome_citta;
    		string provincia;
    		unsigned int n_abitanti;//(facoltativo)
    		vector<string> att_tur;
    };
    
    poi ho:
    
    class Archivio{
    	private:
    		vector<Citta> elencocitta;
    		string attrazione;
    };
    
    quindi per non dichiarare in Archivio altre variabili temporanee ho preferito lo stream passato nella funzione,quindi tu mi consigli di dichiarararmi altre variabili temporanee e passere quelle ai setter?
Devi accedere o registrarti per scrivere nel forum
30 risposte