Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19

Discussione: Aiuto Stream C++

  1. #1

    Aiuto Stream C++

    Buongiorno a tutti,

    premetto che non sono molto esperto in C++ anche se ho già avuto esperienza in merito.

    Il progetto che devo realizzare è una sorta di simulatore di circuiti elettrici (ovviamente molto semplificato e scarno) in cui ci saranno diversi componenti, "n" ingressi e "m" uscite. Il nodo cruciale di questo progetto è proprio il modo con cui vado a rappresentare gli ingressi e le uscite per ogni componente e la mia idea è di rappresentarli tramite una stream di dati.

    Traducendo nel quanto detto sopra nel linguaggio ad oggetti avrò che ogni componente sarà una classe (a partire da una classe base costruisco via via componenti sempre più complessi) e gli ingressi e le uscite saranno una "Stream" di dati "Double".

    Sulla base delle mie conoscenze in materia di C++, so che classi che gestiscono stream di tipo double non ce ne sono; nella classi standard del C++ ho trovato classi che gestiscono stream per i file o per le stringhe ma per dati di tipo double non ne ho trovate. Mi sbaglio?

    Nel caso non mi sbagliassi, cosa mi consigliate di fare? io ho pensato di crearmi una classe che gestisse stream di tipo double ereditando la classe "iostream" ma non so se sia la soluzione migliore (anche perchè mi sono bloccato in quanto non ho ancora ben chiaro come funziona la classe iostream...magari questi dubbi chiederò aiuto successivamente )

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Sia ostream che istream gestiscono senza problemi i double.
    Tradotto in pseudo codice, cosa devi fare esattamente?
    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
    Bene, ti faccio un esempio:

    consideriamo di avere una classe (componente) che prende in ingresso uno stream di dati e fornisce in uscita lo stesso stream di dati moltiplicato per una costante "K".

    La funzione che genera lo stream d'uscita avrà il seguente pseudo-codice:

    codice:
    - crea un nuovo stream "outstream"
    - moltiplica ogni elemento dello stream di ingresso per "K" e mette il risultato in "outstream"
    - restituisce "outstream"
    "iostream" gestisce anche double ma io devo avere come ingresso solo numeri, non devo permettere che vengano inseriti caratteri o stringhe e credo che questa cosa non la posso fare con "iostream".

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    A vederla così, direi che basta un vector di double in cui mettere i dati da elaborare e in cui mettere i risultati.
    Qualcosa di più elaborato potrebbe essere definire due operatori per inserire o estrarre i dati direttamente dalla classe.
    Qualcosa tipo:
    codice:
       ostream << classe_componente;
       istream >> classe_componente;
    Stavi pensando questo per caso?
    In ogni caso non vedo la necessità di creare uno stream apposito per i double.
    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
    Si, esatto stavo pensando di definire due operatori ed usarli come mi hai mostrato.

    Si effettivamente anche io avevo pensato di usare un vettore di double ma poi la necessità di usare uno stream è nata dal fatto che potrei non conoscere la lunghezza e il tipo di dati in ingresso.

    In ogni caso come potrei implementare:

    ostream << classe_componente;
    istream >> classe_componente;

    ma più in generale:

    classe_ingresso >> classe_componente1 >> classe_componente2 >> classe_uscita

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da lucagiuliodori8
    Si effettivamente anche io avevo pensato di usare un vettore di double ma poi la necessità di usare uno stream è nata dal fatto che potrei non conoscere la lunghezza e il tipo di dati in ingresso.
    Se è per questo a un vector si possono aggiungere elementi tramite una pusk_back, quindi la lunghezza non è un problema. Il tipo di dati, hai detto che devono essere double quindi non vedo il problema.

    In ogni caso come potrei implementare:
    ostream << classe_componente;
    istream >> classe_componente;
    Hai due strade:
    la prima e più semplice è definire la coppia di operatori per ogni singola classe.
    codice:
       class Componente {
           public:
           friend std::ostream& operator<<(std::ostream& os, const Componente& comp) {
               // qui si ha accesso a ogni dato privato.
           }
    
           friend std::istream& operator>>(std::istream& os, Componente& comp) {
               // qui si ha accesso a ogni dato privato.
           }
         
       };
    La seconda prevede lo stesso schema, ma solo nella classe base e l'accesso alle classi derivate avviene attraverso una o più funzioni virtuali.
    codice:
       class ComponenteBase {
           public:
           friend std::ostream& operator<<(std::ostream& os, const ComponenteBase & comp) {
              // qui si ha accesso a ogni dato privato.
              os << comp.get_internal_data();
              return os;
           }
    
           friend std::istream& operator>>(std::istream& os, ComponenteBase & comp) {
               // qui si ha accesso a ogni dato privato.
           }
           private:
               virtual double& get_internal_data(); 
       };
    Una spiegazione più dettagliata (in inglese) la trovi a:
    http://www.parashift.com/c++-faq-lite/input-output.html
    [15.8] e seguenti
    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.

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Scusa ma perchè? Dopotutto ogni bipolo ha solo due incognite: tensione e corrente. (E nei multipolo, sono sempre tensioni e correnti, ma non so se li vuoi inserire se il simulatore deve essere semplice).

    Quindi ti basterebbe una classe fatta più o meno così:

    codice:
    class Componente
    {
        private:
            double _corrente;
            double _tensione;
    
        public:
            virtual double applica_tensione(double tensione) = 0;
            virtual double applica_corrente(double corrente) = 0;
    
            virtual double corrente() = 0;
            virtual double tensione() = 0;
    }
    In questo modo usando i metodi corrente() e tensione() puoi leggere la grandezza che ti interessa.
    Se sai la tensione che c'è sul componente, chiami applica_tensione(), se sai la corrente, usi applica_corrente(), calcolando l'altra grandezza usando la relazione costitutiva del componente.

    P.S: ovviamente i metodi devono essere dei pure virtual: virtual così viene chiamato quello del componente derivato, pure virtual per fare in modo che non puoi istanziare una variabile di tipo Componente.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  8. #8
    Per "shodan": grazie mille per le dritte, appena posso mi metto a implementare (e soprattutto capire un po meglio ) il codice e in ogni caso ti farò sapere.

    Per "Ippo343": si effettivamente dando una prima occhiata al problema potresti aver ragione ma se per esempio devo somministrare ad un componente una serie di valori come risultato di un campionamento, risulta scomodo (e sconveniente per le prestazioni) dover chiamare la funzione "applica_tensione" o "applica_corrente" per ogni nuovo valore. Poi in teoria di funzione di ingresso ne servirebbe solo una in quanto tensione e corrente sono comunque correlate dalla funzione di trasferimento del componente.
    Inoltre dovrò anche implementare un componente con più ingressi e una sola uscita ma anche un componente con un solo ingresso e più uscite.


    Grazie ragazzi per il supporto e per i consigli.

  9. #9
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Originariamente inviato da lucagiuliodori8
    Per "Ippo343": si effettivamente dando una prima occhiata al problema potresti aver ragione ma se per esempio devo somministrare ad un componente una serie di valori come risultato di un campionamento, risulta scomodo (e sconveniente per le prestazioni) dover chiamare la funzione "applica_tensione" o "applica_corrente" per ogni nuovo valore.
    Non sono d'accordo. Se ti interessa il campionamento di un solo componente, allora non è importante, ma se devi campionare il comportamento di tutto il circuito, tensione e corrente si devono propagare agli altri componenti, quindi per ogni ingresso ti serve immediatamente l'uscita, dato che deve andare ad un altro componente. O così, oppure non ho capito il problema ^^

    In ogni caso, quello che tu vuoi realizzare con uno stream a me sembra molto più una coda che uno stream.

    Poi in teoria di funzione di ingresso ne servirebbe solo una in quanto tensione e corrente sono comunque correlate dalla funzione di trasferimento del componente.
    Vero, ma ti serve risolta sia rispetto alla tensione che alla corrente. Se fosse una resistenza, ad esempio:

    codice:
    class Resistore : public Componente
    {
        protected:
            double R;
    
        public:
            Resistore(double resistenza) { R = resistenza; }
    
            virtual void applica_tensione(double tensione) {
                _tensione = tensione;
                _corrente = tensione / R;
            }
    
            virtual void applica_corrente(double corrente) {
                _corrente = corrente;
                _tensione = corrente * R;
            }
    };
    Vedi che anche se la resistenza ha una sola relazione, ti serve risolta sia rispetto alla corrente che alla tensione.

    codice:
    Inoltre dovrò anche implementare un componente con più ingressi e una sola uscita ma anche un componente con un solo ingresso e più uscite.
    Beh anche i multipoli, anche se sono un po' complicati, hanno pur sempre n relazioni tra i vari morsetti. Perciò ti basterebbe specificare a quali morsetti si applica la tensione o la corrente.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  10. #10
    Per "shodan":

    ho implementato la seconda soluzione, quella in cui uso una classe base (l'avevo già prevista).
    Il codice che ho sviluppato è il seguente:

    File header:
    codice:
    .
    .
    .
    	friend std::ostream& operator<<(std::ostream&, const ComponentBase&);
    
    	friend std::istream& operator>>(std::istream&, ComponentBase&);
    .
    .
    .
    File cpp
    codice:
    .
    .
    .
    std::ostream& operator<<(std::ostream& os, const ComponentBase& comp)
    {
    	//TODO
    	return os;
    }
    
    std::istream& operator>>(std::istream& is, ComponentBase& comp)
    {
    	//TODO
    	return is;
    }
    .
    .
    .
    Ora se non mi sbaglio, nell'implementazione della funzione che esegue l'overload degli operatori, dovrei andare a scrivere una funzione "virtuale" (magari pura) che sarà poi implementata nelle classi derivate e che caratterizza il comportamento dei singoli componenti giusto? (un po come mi hai suggerito tu con
    codice:
    os << comp.get_internal_data();
    ).


    Per "Ippo343": il campionamento non è del circuito ma di una grandezza fisica di ingresso. Per esempio, supponiamo di avere un file di testo dove all'interno ci sono "n" valori che rappresentano un segnale campionato e sottoposto a conversione A/D per un certo periodo di tempo.
    Se utilizzo il tuo metodo, ad ogni valore letto dal file dovrei chiamare in cascata tutte le funzioni che rappresentano ogni singolo componente per avere alla fine un valore di uscita.
    Se invece utilizzo il metodo che suggerisco io, potresti leggere tutto il file, depositarlo in un vettore e far processare i dati via via un componente alla volta. Ci sarà una latenza tra l'inizio e la fine ma è una cosa accettabile.
    Tutti i dispositivi di elaborazione di segnali digitali lavorano in più o meno in questo modo.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.