Operatoren für eigene Double Klasse



  • Gut, aber was wäre denn dann die Alternative? Ich müsste für jede Variable die ein Setter setzen kann eine eigene Setter Klasse schreiben die dann den den entsprechenden Setter.value speichert. Also z.B.

    class IntSetter
    {
        int value;
    }
    
    class DoubleSetter
    {
        double value;
    }
    
    class ControlSetter
    {
        Control value;
    }
    
    //50 Steuerelemente später...
    
    class TabItemSetter
    {
        TabItem value;
    }
    

    Und dann stehe ich wieder vor dem selben Problem. Ich muss nämlich (explizit) feststellen von welchem Typ der Setter ist wenn ich ihn anwenden will also den Setter.value abrufen möchte.

    Was mir noch einfällt wäre ich gebe der Setter Klasse für jeden Datentyp einen Zeiger:

    class Setter
    {
        int *value;
        double *value;
        Control *value;
        //...
        TabItem *value;
    }
    

    Allerdings muss ich ja dann auch wieder eine Rückgabefunktion haben für jeden Zeiger. Den zurückgegebenen Zeiger prüfe ich dann, ob er ungleich null ist. Das ist einfach Wahnsinn. Das würde den Code enorm aufblähen.


  • Mod

    struct Foo
    {
      int a;
      double b;
      void set(double bb){b=bb;}
      void set(int aa){a=aa;}
    };
    
    int main()
    {
      Foo bar;
      bar.set(5);
      bar.set(3.124);
      cout<<bar.a<<' '<<bar.b<<'\n';
    }
    


  • Kann es sein dass wir gerade aneinander vorbeigeredet haben. Also bei mir ist jede Klasse im Projekt von der Klasse "Object" abgeleitet. Ist

    (Double)obj
    

    dann überhaupt eine explizite Typumwandlung da ja Double von Object abgeleitet ist?
    Ist auch eigentlich egal. Eignetlich wollte ich ja wissen welche Operatoren ich der Klasse im ersten Post noch hinzufügen/entfernen muss damit die Klasse mit dem Datentyp "double" zusammenspielt.



  • So ich habs. Ich musste einige Operatoren rausschmeißen und den Operator

    operator double() const;
    

    hinzufügen. Jetzt funktioniert es so wie ich es mir vorgestellt habe. Ob die Rechenoperationen auch richtig sind habe ich allerdings noch nicht getestet ;).

    class Double : public Object
    {
    public:
    	Double();
    	Double(double value);
    	//Double(float value);
    	//Double(int value);
    
    private:
    	double value;
    
    public:
    	//friend bool operator==(Double const& lhs, Double const& rhs);
    	//friend bool operator<(Double const& lhs, Double const& rhs);
    	Double& operator=(const Double& rhs);
    	Double& operator++();
    	const Double operator++(int);
    	Double& operator--();
    	const Double operator--(int);
    	Double& operator+=(Double const& rhs);
    	Double& operator-=(Double const& rhs);
    	Double& operator*=(Double const& rhs);
    	Double& operator/=(Double const& rhs);
    
    	operator double() const;
            /*operator float() const;
    	operator int() const;*/
    };
    

    Erstaunlich das die ganzen Operatoren nicht notwendig waren:

    /*const Double operator+(Double const& lhs, Double const& rhs);
    const Double operator-(Double const& lhs, Double const& rhs);
    const Double operator*(Double const& lhs, Double const& rhs);
    const Double operator/(Double const& lhs, Double const& rhs);
    bool operator!=(Double const& lhs, Double const& rhs);
    bool operator<(Double const& lhs, Double const& rhs);
    bool operator>(Double const& lhs, Double const& rhs);
    bool operator<=(Double const& lhs, Double const& rhs);
    bool operator>=(Double const& lhs, Double const& rhs);*/
    

    Was ich jetzt aber noch gerne wüsste ist, ob diese Klasse eurer Meinung nach noch verbesserungswürdig ist und ob die folgende Umwandlung nun implizit oder explizit ist?

    class Double : public Object {...}
    Double *d = new Double();
    Object *obj = d; //Implizit oder explizit?
    


  • Kann evtl. ein Moderator die hier entstandene Diskussion abtrennen. Meine Fragen gehen ganz unter ;).



  • Zu dir, Student83:

    • const Double würde ich nicht als Rückgabetyp verwenden. Double reicht. Denn (a + b) = c; ist kein Fehler, der immer wieder passiert und verboten gehört. Auch wenn es immer noch Leute gibt, die so argumentieren.
    • Wenn deine Klasse nur einen einzigen double enthält, würde ich sie jeweils als Kopie und nicht als Referenz auf const übergeben.

    Und warum sind die globalen Operatoren nicht nötig?

    Bei diesem Beispiel

    Double *d = new Double(); 
    Object *obj = d;
    

    führst du mit der zweiten Zeile einen impliziten Upcast von Double zur Basisklasse Object durch. Upcasts (in Richtung Basisklasse) sind immer implizit möglich (ausser bei Mehrdeutigkeiten durch Diamonds of Death, aber das ist hier unwichtig).



  • Nexus schrieb:

    Zu dir, Student83:
    [list][*] const Double würde ich nicht als Rückgabetyp verwenden. Double reicht. Denn (a + b) = c; ist kein Fehler, der immer wieder passiert und verboten gehört. Auch wenn es immer noch Leute gibt, die so argumentieren.

    Die Operatoren hatte ich so mehr oder weniger alle von hier genommen:
    www.c-plusplus.net/forum/232010
    und das const einfach übernommen. Das mit dem const ist mir sowieso noch ein Rätsel. Habe da schon zig unterschiedliche Versionen gesehen:

    const Double operator/(Double const& lhs, Double const& rhs);
          Double operator/(Double const& lhs, Double const& rhs) const;
    const Double operator/(const Double& lhs, const Double& rhs);
    

    Gibt es da eine Regel wo das const denn nun hingeschrieben wird?

    Nexus schrieb:

    Und warum sind die globalen Operatoren nicht nötig?

    Das wüsste ich auch gern. Zumindest funktioniert es jetzt tadellos. Klammere ich die Operatoren wieder aus bekomme ich Fehler wie:
    "error C2666: '::operator -' : 2 overloads have similar conversions"

    Noch eine weitere Frage. Und zwar habe ich den "="-Operator folgendermaßen implementiert:

    void swap(Double& a, Double& b)
    {
    	Double c(a); a=b; b=c;
    }
    
    Double& Double::operator=(const Double& rhs)
    {
    	if (this != &rhs)
    	{
    		Double tmp(rhs);
    		swap(*this, tmp);
    	}
    	return *this;
    }
    

    Was dazu führt dass sobald ich einem Double einen Wert zuweise (z.B. Double d = 42) sich das Programm ohne Fehlermeldung einfach beendet. Der Fehler liegt wohl an der swap-Funktion. Klammere ich diese aus geht es. Auch mit std::swap(*this, tmp); beendet sich das Programm automatisch.

    Und warum schreibt man eigentlich nicht stattdessen nur:

    Double& Double::operator=(const Double& rhs)
    {
    	value = rhs.value;
    	return *this;
    }
    

    So brauche ich keine temporäre Variable der ich noch den Wert von rhs zuweisen muss. Und Swappen brauche ich auch nicht?

    Und noch ein Hinweis an die Moderatoren. Bitte verlängert doch mal die Zeit nach der man hier automatisch abgemeldet wird. Ich habe es noch nicht geschafft einen Beitrag zu schreiben ohne dass ich mich neu einloggen musste ;).


Anmelden zum Antworten