+ Operator für eigenen Datentyp



  • dahaack schrieb:

    Wie mach ich das denn jetzt mit einem + Operator? Da will ich den linken Summanden ja nicht überschreiben, sondern nur das Zwischenergebnis nach links reichen.

    LONGINT operator + ( const LONGINT & lhs , const LONGINT & rhs )
    {
     LONGINT temp ( lhs );
     return temp += rhs;
    }
    

    Oder natürlich auch gleich die einzelnen Werten nehmen, addieren und dann ein neues Objekt erzeugen.

    EDIT:
    Natürlich musst du dazu auch zuerst den += - Operator definieren. Der ist aber prinzipiell dem = - Operator sehr ähnlich.



  • Leider bekomm ichs noch nicht hin. Der += Operator funzt. Beim + werden 2 Fehlermeldungen ausgegeben:

    class LONGINT {
    public:
    	bool bit[48];
    	LONGINT();
    	LONGINT(double zahl);
    	LONGINT& operator=(const LONGINT &zahl);
    	LONGINT& operator+=(const LONGINT &zahl);
    	LONGINT& operator+(const LONGINT & lhs, const LONGINT & rhs ); //error C2804: binary 'operator +' has too many parameters
    	double toDouble();
    
    };
    
    void main() {
    	LONGINT zahl1=120;
    	LONGINT zahl2=-10;
    	LONGINT zahl3(10);
    	zahl3=zahl1+zahl2; //error C2676: binary '+' : 'class LONGINT' does not define this operator or a conversion to a type acceptable to the predefined operator
    	printf("%g\n\n", zahl3.toDouble());
    	printf("%i\n\n", (int)(1&1));
    }
    
    LONGINT operator + ( const LONGINT & lhs , const LONGINT & rhs )
    {
     LONGINT temp ( lhs );
     return temp += rhs;
    }
    


  • Der Operator + sollte auch keine Memberfunktion sein. Verändert ja an keinem der beiden Objekte etwas. Also nimm sie einfach raus.



  • Die Memberfunktion ist die

    LONGINT& operator+(const LONGINT & lhs, const LONGINT & rhs );
    

    ?

    Wenn ich die Zeile rausnehme sagt er bei

    zahl3=zahl1+zahl2;
    

    error C2676: binary '+' : 'class LONGINT' does not define this operator or a conversion to a type acceptable to the predefined operator

    Ich checks nicht.



  • class LONGINT {
       // ...
    
       friend LONGINT operator+( const LONGINT&, const LONGINT& );
    };
    
    LONGINT operator+( const LONGINT& lhs, const LONGINT& rhs )
    {
       // Implementation
    }
    

    oder alternativ (z.B. für Einzeiler)

    class LONGINT {
       // ...
    
       friend LONGINT operator+( const LONGINT& lhs, const LONGINT& rhs ) { /* Implementation */ }
    };
    

    Was wichtig ist, ist zu bemerken, dass in beiden Fällen der operator+ KEINE Memberfunktion ist (der aufruf foobar.operator+( foo1, foo2 ) ist ungültig, da es eine Memberfunktion operator+ nicht gibt).



  • Jo, es funktioniert, Danke!

    Aber was ist denn jetzt eine Memberfunktion? Bei wiki steht:

    Memberfunktionen (auch Elementfunktionen oder Methoden genannt) sind innerhalb einer Klasse deklarierte Funktionen. In einem konsequent objektorientiert geschriebenen Programm sollte jede Funktion außer der Funktion main() Memberfunktion einer Klasse sein.

    Dadurch bin ich ja jetzt auch nicht viel schlauer geworden.



  • friend-Funktionen können keine Member-Funktionen der Klasse selber sein (und es würde freilich auch wenig sinn machen, weil Memberfunktionen ja sowieso Zugriff auf private-Member der Klasse haben).
    Im ersten Fall sagst du innerhalb der Klassendefinition nur, dass es eine "globale" Funktion operator+(...) gibt, die Zugriff auf alle Member der Klasse hat. Im zweiten gibst du auch gleich noch den Funktionsrumpf für diese Funktion mit.
    In Worten des Standards kann ich das aber leider im Moment nicht ausdrücken. Da muss mir hier mal einer der Gurus aushelfen 😉

    Viele Grüße,
    Michael



  • In C++ ist es eine Memberfunktion, wenn implizit der this Zeiger mitgegeben wird. Also alle Funktionen, die du innerhalb einer Klasse deklarierst, ausser statische und friend-Funktionen.



  • Naja, eine friend-Funktion kann ja durchaus eine Memberfunktion sein, nur nicht in der Klasse, in der sie als friend deklariert wird.

    void globalFunc(); // keine Memberfunktion
    
    class a {
       void func1();             // Memberfunktion von a
       friend void globalFunc(); // Keine Memberfunktion
       static void func2();      // Statische Memberfunktion
    };
    
    class b {
       void func1();             // Memberfunktion von b
       friend void a::funct1();  // Keine Memberfunktion von b (aber von a!)
    };
    


  • Berichtigung:
    Funktionen, die in einer Klasse definiert sind, ausser denen, die mit friend deklariert sind, sind Memberfunktionen. Wenn sie mit static deklariert ist, ist es eine statische Memberfunktion, ansonsten eine nicht-statische Memberfunktion dieser Klasse.
    Eine statische Funktion hat keinen this-Pointer. (eine friend-Funktion oder Klasse ebensowenig).

    @Decimad:

    static void func2();      // Keine Memberfunktion
    

    Laut Standard ist das eben eine Memberfunktion, aber halt eine statische. 😉



  • Wenn das mal nicht kompliziert ist 😉

    PS: Korrigiert, danke!



  • dahaack: es wäre vielleicht sinnvoll, wenn du dir ein paar Grundlagen zur Operatorüberladung anschaust. Wichtige Punkte sind dabei:
    - Welche Operatoren sollte man als Klassenmember implementieren, welche als freie Funktionen?
    - Wie sieht die typische Funktionssignatur der Operatoren aus (Argumente, Rückgabetyp, const oder nicht, Referenz oder nicht usw.)
    - Wie sehen typische Implementierungen aus (z.B. copy&swap für op=, op+ mittels op+= implementieren usw.)

    dazu noch einen kleinen Tip, der früher oder später in der einen oder anderen Form sowieso gekommen wäre:
    Sätze wie "Ich krieg eine Fehlermeldung" oder "Das funktioniert nicht" werden hier im Forum gerne mal mit Hinweisen auf defekte Glaskugeln gahndet. Wenn du nicht dazuschreibst wie die Fehlermeldung lautet oder wie sich das "nicht funktionieren" äußert (Absturz, Kompilierungsfehler, unerwartetes Verhalten,...) kann man meist nur raten oder sich deinen Code durchlesen. Wenn du Fehlermeldungen angibst weiß meist jemand ziemlich genau wonach man suchen muss, und der Fehler ist schnell gefunden 😉



  • Okay, vielen Dank an alle!


Anmelden zum Antworten