Was macht cout << cin?

  • huhu ihrs :)

    wenn ich
    cout << cin;
    mache, wird eine Adresse ausgeben.
    Was ist das für eine Adresse bzw. zu wem gehört diese Adresse?

    Danke euch :)

    Einmal editiert, zuletzt von The User (26. April 2009 um 15:24) aus folgendem Grund: Aussagekräftiger Titel

  • Hi!
    Man kann etwas probieren:
    Es gibt zwei Möglichkeiten in C++, den <<-Operator zu überladen, einmal als Elementfunktion und einmal als globale Funktion. Der zweite Weg ist üblicher, also kann man es einmal probieren:

    Code
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
      operator<<(cout, cin);
    }


    Das kompiliert nicht, die Funktion existiert nicht. Folglich muss es eine Elementfunktion sein:

    Code
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
      cout.operator<<(cin);
    }


    >> Geht und führt zur selben Ausgabe.
    Sieht doch aus wie eine Pointer-Adresse, das wollen wir einmal testen:

    Code
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
      cout << &cin << endl << cin;
    }


    Ausgabe:

    Zitat


    0x804a040
    0x804a048


    Es ist nicht die Adresse von cin, aber die Ähnlichkeit fällt doch auf.
    Mit cout sieht die Ausgabe recht ähnlich aus, vermutlich klappt es wohl auf jedem ios oder ios_base geht.
    Dazu finden wir hier jedoch keine Funktion operator<< mit ios oder ios_base als Operanden.
    Folglich muss eine Konvertierung stattgefunden haben, in ios finden wir operator void*.

    Code
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
      cout << (void*)cin << endl;
      cout << cin;
    }


    Die beiden Ausgaben sind identisch!
    Das Ergebnis hat laut Doku keine besondere Bedeutung, außer es ist 0, dann ist der interne Status einer, der einen Fehler anzeigt. Warum ein operator void* und kein operator bool verwendet wurde, ist mir schleierhaft.

    Viele liebe Grüße
    The User

    PS:
    driver
    In der Praxis ist das keine entscheidende Frage, ich glaube es war nur Interesse und kein wirkliches Problem. ;)
    PPS:
    Die Rückgabe der Funktion ios::operator void* ist vom Compiler abhängig:
    Visual C++:

    Code
    operator void *() const { if(state&(badbit|failbit) ) return 0; return (void *)this; }


    Hierbei wird die Konvertierung im C-Stil geschrieben, was zu Unklarheiten führt.
    Anders sieht es beim GNU Compiler in basic_ios (das ist ein Implementierungs-Detail) aus (abgesehen von der besseren Kommentierung, Einrückung und Lesbarkeit!):

    Code
    operator void*() const
          { return this->fail() ? 0 : const_cast<basic_ios*>(this); }


    Explizit wird klar gemacht, dass ein const_cast stattfindet, denn der Typ von this in einer Funktion mit const nach den Klammern ist const basic_ios*. Anschließend findet implizit die Konvertierung in void* statt, die selbstverständlich sein sollte.
    Wenn mehrfache Vererbung ins Spiel kommt, ist die Adresse nicht mehr unbedingt diejenige, die man durch (void*)cin erhält. Dadurch weichen die Zahlen leicht ab.
    Es sollte klar sein, dass du den Rückgabewert dieser Funktion nicht verwenden solltest außer als boolean!