Klasse, deren Objekte sich wie primitive Datentypen verhalten.



  • Hallo C++ler,

    Nehmen wir die folgende Deklaration einer Klasse an:

    template <class T>
    class SomeValue
    {
        public:
            T value;
    
            SomeValue( T value ): value( value ) {}
    };
    

    Gibt es eine Möglichkeit, dass ein Objekt dieser Klasse selbst den Wert repräsentiert, also dass

    int main()
    {
        SomeValue<double> real( 3.1415 );
    
        std::cout << real << std::endl;
    
        return 0;
    }
    

    den Wert "3.1415" ausgibt (ohne Definition des operators<< für diese Klasse)?

    Vielen Dank.



  • Ganuz ohne Operatorenüberladung wirst du nicht auskommen, denk ich, aber wenn dir << zu viel Aufwand oder zu spezifisch ist könntest du die entsprechenden Konvertierungsoperatoren definieren.



  • Ich weiß nicht ob das hinhaut:

    template <class T> 
    class foo {
        T operator T();
    };
    

    vielleicht ?



  • Die Ausgabe via "std::ostream" sollte nur ein Beispiel sein. Mir geht es vielmehr darum, dass das Objekt "real" im obigen Beispiel selbst den Wert "T" (also double) annimmt, denn dafür gäbe es ja einen Operator <<.

    Vielen Dank.


  • Mod

    Ich glaube was du suchst ist ein Konvertierungsoperator.

    operator double(){return value;}
    

    Das funktioniert natürlich nur, wenn der Kontext eindeutig ist.

    Aber: Genau für das gezeigte ist die Operatorüberladung doch da, warum willst du sie nicht benutzen?



  • template <class T>
    class SomeValue
    {
      T value;
    public:
      SomeValue(T value) : value(value) {}
      operator T() const { return value; }
    };
    

    So geht das.



  • Oder noch besser so:

    #define implicit // contrary of `explicit' keyword
    template <class T>
    class SomeValue
    {
      T value;
    public:
      implicit SomeValue(T value) : value(value) {}
      operator T () const { return value; }
      operator T&()       { return value; }
    };
    

    Gebrauch:

    SomeValue<double> real(3.14159);
    std::cout << real << std::endl;
    double d = 2 * real;
    std::cin >> real;
    real = std::pow(d, real);
    std::cout << real << std::endl;
    

    Verhält sich wie ein normaler double.



  • Super. Vielen Dank.

    Genau was ich gesucht habe 🙂

    Grüße



  • Benutzt aler auch "operator-Überladung" - nur halt nicht von jedem einzeln, sondern nur vom Konvertierungsoperator.

    Gruß,

    Simon2.



  • Aber vor der extensiven Verwendung dieses Operators wird nicht umsonst gewarnt!

    In vielen Faellen in der Praxis wo mir das unterkommt ist es nicht nuetzlich sondern eher gefaehrlich (weil die typpruefung von c++ überlistet/ausgehebelt wird).
    In anderen aber wenigen Faellen ist es wiederum durchaus Sinnig. Also mit Bedacht verwenden !

    in den meisten Faellen wo die impliziete konvertierung nicht sinnvoll ist, ist die Überladung aller benoetigten operatoren der bessere Weg. Ist zwar mehr Aufwand, man hat aber viel mehr kontrolle.
    Und Lösungen nur weil sie weniger SchreibAufwand bedeuten -> schlechte Lösungen.

    Also bleibt die Frage:
    Wenn sich das Ding bspweisse verhalten soll wie in double, warum ist es dann kein double ? Warum willst du den double quasi ersetzen ?

    Ciao ...



  • flowerJT schrieb:

    Genau was ich gesucht habe 🙂

    Nein! Ob du nun den Streamoperator << ueberlaedst oder einen Konvertierungsoperator implementierst, ist ja egal. Uebrigens ist ja Operatorueberladung genau dafuer da, dass sich eigene Typen wie primitive verhalten. Aus Faulheit sich diese zu sparen, ist meist keine gute Idee.


Anmelden zum Antworten