Variable eines eigenen Datentyps ausgeben



  • Hallo zusammen,

    ich arbeite gerade mit einer Klasse namens "Biggy" (siehe C++ Forum), die mit großen Werten rechnen kann. Ich kann die Ergebnisse in der Konsole auch ausgeben, doch nun möchte ich das Ergebnis auf ein Label oder in einer MessageBox ausgeben lassen, doch die können natürlich nichts mit "Biggy" anfangen.

    Könnt ihr mir helfen, einen eigenen Datentyp in einen String umzuwandeln? Geht das überhaupt?

    Das geht jedenfalls nicht:

    ShowMessage(fac< Biggy >( 100 ));
    

    Ich weiß jetzt nicht, wie relevant die Klasse "Biggy" ist. Wenn ihr sie benötigt, dann poste ich sie natürlich auch nochmal!

    Vielen Dank
    lg, freakC++



  • Hallo

    Ich kann die Ergebnisse in der Konsole auch ausgeben

    Na dann hast du doch schon eine Funktion, die den internen Wert in einen String gleich welcher Art umwandelt. Um mehr brauchen doch auch die GUI-Controls der VCL nicht.

    bis bald
    akari



  • Hallo akari!

    Ich gebe in der Konsole das Ergebnis mit cout aus. Dazu wird der Operator << verwendet, der die Konvertierung vornimmt.

    friend std::ostream& operator<<( std::ostream& out, const Biggy& b ) 
        {
            const double g = std::floor( b.m_x );
            const std::streamsize prec = out.precision();
            out << std::pow( 10., b.m_x - g ) << "E" << (g>0?"+":"") << std::fixed << std::setprecision(0) << g;
            out.precision( prec );
            return out;
        }
    

    Wie kann ich denn solch eine Methode auf GUI Elemente anwenden? Da kann ich doch ofstream nicht verwenden, oder? Ich habe sowas noch nie gemacht und habe daher nicht viel Ahnung darüber 🙂

    Kannst Du mir ein Beispiel geben?

    Vielen Dank
    lg, freakC++



  • Du kannst aber einen stringstream nehmen. Der liefert dir dann ein std::string und das bekommst du ja problemlos in dein Label.



  • Hallo

    Um Braunsteins Vorschlag zu verdeutlichen :

    #include <sstream> // Hinzufügen
    
    // Deine bisherige Klasse
    class Biggy
    {
      public :
    
    // Dein bisheriger <<-Operator
    friend std::ostream& operator<<( std::ostream& out, const Biggy& b )
        {
            out << "biggy"; // Irgendeine Ausgabe auf dem stream
            return out;
        }
    // Neuer Konvertierungsoperator, der nur im Builder funktionieren wird
    operator AnsiString()
    {
      std::stringstream a;
      a << *this;
      return a.str().c_str();
    }
    
    };
    
    ...
    // Ermöglicht folgenden Einsatz
    Biggy b;
    Label->Caption = b;
    

    bis bald
    akari



  • Genau. 🙂
    Ich würde statt dem Konvertierungsoperator aber lieber eine normale Memberfuntion (toAnsiString oder so) nehmen um keine unangenehmen nebeneffekte zu produzieren.



  • Hallo zusammen,

    akari schrieb:

    operator AnsiString()
    {
      std::stringstream a;
      a << *this;
      return a.str().c_str();
    }
    

    Ich habe es mit eurer Hilfe hinbekommen, doch ich habe zum geposteten Quelltext ein paar Fragen.

    1.) Seit wann ist "AnsiString" ein Operator, den ich überladen kann?

    2.) Ich deklariere einen Stringstream. Laut der Referenz kann ich damit Strings manipulieren, als es ob es ein Ein- / Ausgabstream wäre. Dieser Stringstream Variable wird nun die Adresse des kompletten Objekts zugewiesen. Woher "weiß" der Stringstream, dass a aber nur die zu konvertierende Zahl beinhalten soll und nicht noch andere Attribute?

    3.) Mit str() wird das "associated string object" bekommen. Habe ich das durch die *return Anweisung nicht sowieso schon?

    4.) Warum muss nun alles in einen C - String umgewandelt werden?

    Wie ihr seht, habe ich einige Fragen, doch ich möchte verstehen!!

    Vielen Dank und einen schönen Abend 🙂
    lg, freakC++



  • Hallo

    Seit wann ist "AnsiString" ein Operator, den ich überladen kann?

    AnsiString ist kein Operator, sondern ein Datentyp. Aber du kannst Operatoren definieren, um einen beliebigen Datentyp X in einen Datentyp Y umzuwandeln. Das ist dann sozusagen eine Methode von X mit dem Namen Y. Diese methode wird immer aufgerufen, wenn expliziet oder impliziet von X nach Y umgewandelt werden soll, egal ob Zuweisung oder Konstruktor.

    Ich deklariere einen Stringstream. Laut der Referenz kann ich damit Strings manipulieren, als es ob es ein Ein- / Ausgabstream wäre. Dieser Stringstream Variable wird nun die Adresse des kompletten Objekts zugewiesen. Woher "weiß" der Stringstream, dass a aber nur die zu konvertierende Zahl beinhalten soll und nicht noch andere Attribute?

    Du deklariert mit a einem komplett neuen Stream, schreibst deine Daten rein und mit dem Ende der Methode wird a wieder komplett gelöscht. Woher sollen den andere Attribute herkommen als die, die du selber auf a anwendest? C++ Streams sind auch nur Instanzen wie alle anderen Datentypen auch.

    3.) Mit str() wird das "associated string object" bekommen. Habe ich das durch die *return Anweisung nicht sowieso schon?

    Du willst ja nicht den Stream selber zurückgeben, sondern nur desen Inhalt als einfachen string. Diesen mußt du erstmal aus dem Stream holen.

    4.) Warum muss nun alles in einen C - String umgewandelt werden?

    Die Methode str() gibt einen std::string zurück. Du willst aber einen (Ansi-)String aus der VCL. Die beiden Datentypen sind nicht direkt miteinander kompatibel. Aber als Brücke zwischen beiden kannst du einen C-String benutzen.

    bis bald
    akari



  • Hallo akari,

    danke für deine Mühe. Du hast mir mal wieder sehr geholfen. Ich habe noch eine letzte Frage. Warum wird eigentlich der überladene Operator << aufgerufen, wenn ich das Ergebnis beispielsweise auf ein Label schreiben will. Wird dieser intern aufgerufen, sobald ich mit einem Ausgabestream arbeite? Ich schreibe ja nicht explizit "<<" oder passiert das beim TLabel intern?

    Vielen Dank
    lg, freakC++



  • Hallo

    Die Reigenfolge ist folgendermaßen :
    - Die Zuweisung ruft den Konvertierungsoperator auf, weil der L-Value einen AnsiString erfordert
    - Der Konvertierungsoperator baut einen stringstream auf und wendet den <<-Operator auf diesen stream an, mit sich selber als Parameter
    - Der <<-Operator füllt den stream mit den gewünschten Daten und beendet sich
    - Zurück im Konvertierungsoperator wird der Inhalt des streams als std::string ausgelesen und als C-String zurückgegeben. Der Konvertierungsop. beendet sich
    - Der C-String kann vom Ansistring-Konstruktor übernommen werden. Die Zuweisung wird abgeschlossen.

    bis bald
    akari



  • Super!

    Vielen, vielen Dank! Ich habe es verstanden!

    Liebe Grüße
    freakC++


Anmelden zum Antworten