Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di Kilin
    Registrato dal
    Mar 2003
    Messaggi
    453

    [C++] significato del riferimento nella ridefinizione di un operatore

    Ciao a tutti...

    vi vorrei chiedere un parere: nella ridefinizione ad esempio dell'operatore di uscita, l'intestazione tipica è:

    codice:
    ostream& operator<<(ostream& os,MiaClasse& obj);
    perchè è importante passare "os" per riferimento? qualche idea ce l'ho ma vorrei sentire il vostro parere...

    grazie...

  2. #2
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,565
    Perché devi usare lo stesso oggetto ostream con il quale scrivi di solito...
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  3. #3
    Utente di HTML.it L'avatar di Kilin
    Registrato dal
    Mar 2003
    Messaggi
    453
    uhm... e questo perchè? se lo passassi per valore che cosa cambierebbe? la funzione all'interno lavorerebbe con una copia dell'oggetto ostream con cui scrivo di solito, e questo perchè non andrebbe bene?

    grazie

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Kilin
    uhm... e questo perchè? se lo passassi per valore che cosa cambierebbe? la funzione all'interno lavorerebbe con una copia dell'oggetto ostream con cui scrivo di solito, e questo perchè non andrebbe bene?
    Per due motivi:
    1) non è detto che un oggetto derivato da ostream possa avere operatore di assegnamento o costruttore di copia espliciti e quindi si bloccherebbe la compilazione.

    2) polimorfismo. L'operatore che hai indicato può prendere un cout, un ofstream, un osstream senza fare una piega.

  5. #5
    Utente di HTML.it L'avatar di Kilin
    Registrato dal
    Mar 2003
    Messaggi
    453
    innanzitutto grazie della risposta

    riguardo al punto uno, è proprio quella l'idea che mi ero fatto...

    riguardo al punto due però non mi torna: ammesso che non ci fossero problemi per quanto riguarda il punto uno... mi pare che non ci sarebbero problemi lo stesso, anche senza il riferimento, a passargli un cout piuttosto che un ostream ecc...o mi sbaglio?

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Nel caso specifico di un ostream come cout, nella catena di derivazione, è disabilitato il passaggio per valore. (non ricordo in che punto, forse ios)
    http://www.cplusplus.com/reference/iostream/

    Nel caso l'operatore fosse definito per due classi differenti, si ricade sempre nel doppio passaggio per valore con annessi e connessi.
    Costruttore di copia all'ingresso e all'uscita della funzione e se la classe contiene raw pointer, occorre fare molta attenzione.

    C'è poi un altro caso.
    codice:
    class A {
       public:
           virtual void p() { cout << "A" << endl; } 
    };
    
    class B : public A {
       public:
           void p() { cout << "B" << endl; } 
    };
    void test(A a) { a.p(); }
    
    main() {
       B b;
       test(b);
    }
    test stamperà "A" , non B in quanto si verifica lo slicing della classe.

  7. #7
    Utente di HTML.it L'avatar di Kilin
    Registrato dal
    Mar 2003
    Messaggi
    453
    ora è tutto molto più chiaro, ti ringrazio!

    ho fatto una prova comunque, passando l'ostream per valore:

    codice:
    ostream& operator<<(ostream os, MiaClasse &obj)
    mi si apre "ios_base.h" nel compilatore, a questa riga:

    codice:
      private:
        ios_base(const ios_base&);
    
        ios_base&
        operator=(const ios_base&);
      };
    e mi da questi errori:
    codice:
    In copy constructor `std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)':
    `std::ios_base::ios_base(const std::ios_base&)' is private within this context 
    In function `int main()': 
    initializing argument 1 of `std::ostream& operator<<(std::ostream, MiaClasse&)'
    aiutami a decifrare: io vedo che il costruttore di copia è definito private: quindi in questo si nota che non è previsto un costruttore di copia per un passaggio per valore?

    grazie!

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Esatto. Si verifica il punto 1. Dichiarando private il costruttore di copia si disabilita il passaggio per valore alla funzione e questo vale per ogni classe che eredita da ios_base (o da classi che prevedono lo stesso meccanismo.)

  9. #9
    Utente di HTML.it L'avatar di Kilin
    Registrato dal
    Mar 2003
    Messaggi
    453
    ho capito... grazie davvero, ho capito un po' di cose che mi mancavano, sei stato molto chiaro e disponibile..

    ciao!

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.