Operator überladung bei 2D Vektroren
-
benenne den 2Dvec doch mal so um, dass das erste Zechen ein Buchstaben ist. Z.B.: Vec2D. In C++ darf kein Name mit einer Ziffer beginnen.
-
Dein Klassenname beginn mit einer Ziffer beginnt, das ist nicht erlaubt.
Binäre Operatoren sollten allerdings als freie Funktionen implementiert werden, weil sie flexibler einzusetzen sind als member Funktionen:
Vec2D operator+( const Vec2D& op1, const Vec2D& op2 ) { ... }
-
Man bin ich ein Vollpfosten:D. Ok mit der umbenennung von 2Dvec zu vec2D hat es geklappt:).
DocShoe schrieb:
Dein Klassenname beginn mit einer Ziffer beginnt, das ist nicht erlaubt.
Binäre Operatoren sollten allerdings als freie Funktionen implementiert werden, weil sie flexibler einzusetzen sind als member Funktionen:
Vec2D operator+( const Vec2D& op1, const Vec2D& op2 ) { ... }Wie meinst du das genau? Aber + ist doch nur ein binärer operator und kein tärnärer? Könntest du das ein bisschen besser erklären, evtl. auch mit dem Code?
Und welche vorteile hätte ich durch diese Notation? Ist das schneller? Oder sicherer?
-
das ist ganz einfach. bis jetzt deklarierst du die addition als memberfunktion (also innerhalb deiner klasse). nun sollst du ihn ausserhalb deiner klasse deklarieren.
das hat den vorteil, dass die addition kommutativ ist und zur not können casts durchgeführt werden. bei vec1 + vec2 hat das keine probleme...
aber z.b. bei bruchzahlen (im folgenden b1 und b2): hier wäre b1 + b2 kein problem. aber was ist wenn du eine bruchzahl b mit einer ganzen zahl addieren möchtest?!? b + i wäre das, ok. aber was ist nun i + b?
dann müsstest du ja den plus operator von int überschreiben. wenn du nun aber die addition von den bruchzahlen global deklarierst und auch einen konstruktor hast der als argumetn nur einen int erwartet, castet der compiler das implizit und es funktioniert ===> schreibarbeit gespart
-
aber ich habe doch die Koordinaten von vec2D als double deklariert ... wieso sollte ich da bei brüchen oder integers probleme bekommen ...
Sorry aber ich verstehe immer noch nicht worauf du hinaus willst, bin ein programmieranfänger und deswegen ein bisschen langsam:D.
-
ok, ich versuchs anders zu erklären. ich greife aber das beispiel der bruchzahlen auf, da es bei dem vector nicht wirklich sinn macht.
also erstmal was mathe:
\begin{math} \frac{1}{2} + 1 = \frac{3}{2} = 1,5 = 1 + \frac{1}{2} \end{math}das gilt, wie du wissen solltest. ein-halb plus eins ist gleich eins komma fünf ist gleich eins plus 1-halb (man beachte die kommutativität, also das vertauschen der beiden summanden)
hast du jetzt eine bruchklasse:
class Bruch { int nenner; int zaehler; public: Bruch(int zahler, int nenner = 1) : zaehler(zaehler), nenner(nenner) { } // sicherheitsfunktionen wie assert lasse ich weg, der nenner könnte nun auch 0 sein! Bruch operator+(Bruch const& rhs) { Bruch tmp(this->zaehler*rhs.nenner + rhs.zaehler*this->nenner, this->nenner*rhs.nenner); // bruch addition return tmp; } }; int main() { Bruch a(1, 2); Bruch b(1); // durch default parameter auf 1/1 gesetzt Bruch ergebnis = a + b; // -> 1/2 + 1 = 3/2 = 1,5 ok! Bruch ergebnis2 = b + a; // auch noch ok, weil a und b Bruch instanzen sind Bruchergebnis3 = a + 1; // ok, da 1 wegen dem konstruktor implizit zu einem bruch gecastet werden kann Bruch ergebnis4 = 1 + a; // FALSCH! trotz der + operator überladung return 0; }umgehen kann man dies durch folgendes:
class Bruch { // ... wie oben alles friend Bruch operator+(Bruch const& a, Bruch const& b); }; Bruch operator+(Bruch const& a, Bruch const& b) { Bruch tmp(a.zaehler*b.nenner + b.zaehler*a.nenner, a.nenner*b.nenner); return tmp; } int main() { // .. wie oben, nun funktioniert ergbenis4 jedoch }verstanden soweit?
-
ah jetzt kapiere ich was du sagst:).
Der vec2D operator+ (const &v1) ist also nicht vollkommen kommutativ ...Aber was genau bedeutet denn der Schlüsselbegriff friend?
friend Bruch operator+(Bruch const& a, Bruch const& b);ich kenne nur public, private und protected(obwohl ich den unterschied zu private nicht ganz verstehe:D)
-
DaNewGuy schrieb:
Aber was genau bedeutet denn der Schlüsselbegriff friend?
friend bedeutet, dass das, was da als "Freund" deklariert wird, zwar (syntaktisch) nicht zur Klasse gehört, aber dennoch Zugriff auf die privaten Member hat. Das sollte aber auch im Einführungsbuch deiner Wahl stehen.
C++ - where friends can touch your privates, but your family can't.
-
DaNewGuy schrieb:
ich kenne nur public, private und protected(obwohl ich den unterschied zu private nicht ganz verstehe:D)
Nur der Vollständigkeit halber: Dieser Unterschied wird erst relevant, wenn du dich mit Vererbung beschäftigst - protected-Elemente dürfen von den eigenen Methoden, Freunden und den Methoden abgeleiteter Klassen verwendet werden.
-
Wobei protected immer nur für this gilt, die Variablen und Methoden anderer Instanzen sind trotzdem private.
-
pumuckl schrieb:
C++ - where friends can touch your privates, but your family can't.
Ich habe eine neue Signatur.