Hallo Nicos,
Wie würde man das beim X::operator+ realisieren,
ohne dass er seine „überlieferte“ Bedeutung
verliert bzw. der C+±Quelltext an expressiver
Kraft einbüßt?
Ich weiß jetzt nicht, was du meinst.
Ich meine Stroustrups Ansicht, dass
Member-Operatoren nur gebildet werden
sollten, wenn sie Klassendaten verändern,
wie z.B. operator += ()
Um das mal überspitzt auszudrücken hätte er dann vielleicht nicht die Möglichkeit einbauen dürfen, binäre const-Operatoren als Members zu definieren.
Ja, schon klar, aber was passiert hier?
class X {
compound data;
public X operator+ (const& X) {
temp class X; erzeugt nochmal „compound data“
innerhalb X
…
return temp
}
}
Alles klar?
Auch bei 2-Para Operatormethoden wird ein temporäres Objekt auf dem Stack erzeugt, anders könnte man ja z.B. Ausdrücke wie a=b+c schlecht realisieren. Von irgendwo muss ja das „=“ seinen rechten Operand bekommen, und wenn man von extrem spezialisierten Optimierungen (z.B. Chaining oder implizite Erzeugung von entsprechenden 3- oder höherwertigen Operatoren (viel Spass dabei )) mal absieht, wird das wohl immer in einem neuen Objekt auf dem Stack resultieren. Lediglich der linke Operand ist in diesem Fall halt festgelegt, und man braucht noch nicht mal einen potentiell riesigen „friend“-Block. (Eine Klasse die ich grade vor mir habe hat 8 const-Operatoren, wenn man selber welche definieren könnte wären es 18 für diverse andere Operationen.)
Schon klar, aber 2 Probleme bei
2-Para-Member-Operatoren, (wie Du weisst):
- keine implizite Typkonvertierung bei trivialen
Konvertierungen
ACK für das linke Argument. Allerdings wird man in vielen Fällen sowieso wissen, mit welchem Typ man es zu tun hat und kann des Cast genauso gut explizit vornehmen. Das hat wohl auch Vor- und Nachteile, aber bei dem Typengewusel in C++ vertrete ich die Meinung, dass ein expliziter Cast zuviel besser ist als einmal falsche Hoffnung an der falschen Stelle.
- bei mehrfacher Anwendung werden immer neue Klassen in
der Klasse (auf dem Stack) erzeugt
Der Stack ist (normalerweise) nicht an die Klasse gebunden. Auch nicht-Memberoperatoren müssen wie erwähnt ein passendes temporäres Objekt zurückliefern, das dann genauso auf dem Stack der die Methode aufrufenden Funktion landet.
Sowohl Stroustrup als auch Koenig/Moe (ISBN: 0201423391 Buch anschauen)
erklären es daher „zum guten Stil“, 2-Parameter-Operatoren
nicht als member und besser ggf. als friends zu deklarieren.
Andere vertreten die Meinung, dass der „friend“-Mechanismus zumindest seltsam ist und in einigen Fällen die Wartbarkeit nicht unbedingt verbessert. Die einzige Verwendung die ich dafür bisher gefunden habe waren schnelle, hässliche Hacks wenn ich ums Verrecken nicht noch 20 Accessor-Methoden schreiben wollte.
Ohne Zusammenhang: in C++ friends access you but you cant access friends