Zuweisungsoperator überladen?????
-
Hallo, Zuweisungsoperator überladen. Wie geht das?
typedef struct { double x,y,z; } DXYZ; typedef struct { float x,y,z; } XYZ; XYZ A; DXYZ B; D=A;//Da hier soll gehen:
[cpp]
-
Hallo
1. falsches Forum
2. funktion operator =(const classe& temp) überschreiben
3. auf zuweisung an sich selbst im operator prüfen.chrische
-
Es geht um Strukturen nicht um Klassen.
-
Hallo
Da gibt es afaik in c++ keinen Unterschied außer, dass struct default public und class default privat ist.
chrische
-
struct BLAH { int foo; int bar; }; struct BLUBB { short f; short b; }; BLAH& operator = (BLAH& lhs, BLUBB const& rhs) { lhs.foo = rhs.f; lhs.bar = rhs.b; return lhs; } BLUBB& operator = (BLUBB& lhs, BLAH const& rhs) { lhs.f = rhs.foo; lhs.b = rhs.bar; return lhs; }
-
Hallo
Warum machst du das als freie Funktionen udn nciht als member?
chrische
-
Warum nicht?
Wenns schon structs sind (und alles public ist), und die Zuweisung zwischen 2 unverwandten Klassen passiert, wieso sollte ich es dann als Member machen?
Irgendein Vorteil?
Denke nicht...Freie Funktionen sind dein Freund...
-
Hallo
Ich wollte nur wissen, ob deine methode einen besonderen Vorteil hat. Ich habe so etwas bisher immer als member realissiert, aber ich arbeite auch nie mit structs, sondern immer mit class.
chrische
-
Dieser Thread wurde von Moderator/in estartu aus dem Forum MFC (Visual C++) in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
hustbaer schrieb:
Freie Funktionen sind dein Freund...
Wenn sie denn erlaubt sind. Und afaik muß op= als Methode der Ziel-Klasse definiert werden (auch wenn diese ein struct ist).
-
Ich hab da gerade mal nachgeschaut.
siehe standard 12.8 9A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&....
-
Ihr habt Recht. Ich war mir sicher das schonmal so verwendet zu haben, da sieht man wieder wie man sich irren kann. Hm. Wird wohl operator == gewesen sein.
Irgendwie doof, IMHO macht die Regel genau garkeinen Sinn, aber whatever.
-
hustbaer schrieb:
Irgendwie doof, IMHO macht die Regel genau garkeinen Sinn, aber whatever.
Doch, sie hat ein einen Sinn. Ansonsten könnte man nämlich über einen impliziten Konstruktor eine Konversion erzeuge und folgenden Code schreiben:
struct foo { foo(int); }; int i; foo f; i = f;
Eventuell soll solcher Code vermieden werden. Mir ist klar, dass man diesen Code erzeugen kann, indem man einen 'operator int' für 'foo' definiert – der Effekt ist aber ein anderer. Im obigen Code wurde nämlich die Semantik des op= für 'int' verändert (nein; in Wahrheit passiert das natürlich nicht, es hat aber den Effekt).
/EDIT: Es gibt einen viel einfacheren Grund: Um sicherzustellen, dass sich auf der linken Seite eines op= stets ein lvalue befindet. Das müsste ja sonst nicht zwangsläufig der Fall sein.
-
Dass auf der linken Seite nen lvalue steht könnte man auch so verlangen. Ich sehe immer noch keinen Grund.
Aber egal, ist so, ich werde versuchen es mir zu merken
-
Es gibt einen Grund, dass op= bei Klassen Member ist: bei einer Zuweisung a=b wird das Objekt a verändert. Als Memberfunktion kann operator=() auf alle Attribute zugreifen. Das wäre bei einer freien Funktion nicht möglich (friend sollte weitgehend vermieden werden), es sei denn, es gibt entsprechende public-Funktionen zum Setzen der Attribute. Diese Funktionen müssten innerhalb einer freien Funktion aufgerufen werden. Solche Setter-Funktionen will man aber vielleicht gar nicht haben, weil sie evtl. interne Verwaltungsinformationen beträfen und von jedem benutzbar wären. Generell sollen daher verändernde Funktionen Member der Klasse sein. Dies gilt auch für Operatoren wie +=, *= usw. Die zugehörigen Gegenstücke wie +, * usw. sollten dann freie Funktionen sein, die ihrerseits +=, *= usw aufrufen können. Natürlich - wenn nur structs im Spiel sind, ist es egal, was die reine Funktion angeht, aber was ist, wenn die structs mal zu Klassen werden sollen? Ein Entwurf mit op= als Member würde Änderungsaufwand sparen helfen.
-
UBr schrieb:
friend sollte weitgehend vermieden werden
Das ist so falsch. Speziell im Kontext von Operatoren spricht *nichts* gegen die Verwendung von 'friend' (außer, dass man es meistens nicht braucht, weil man '+', '-' etc. sowieso besser über '+=' etc. implementieren sollte).
-
Als freie Funktion würde es helfen dependencies zu vermeiden, bzw. wenigstens etwas "auseinanderzuschieben".
- Klasse A, Klasse B, operator A = B als Member von A: A depends on B
- Klasse A, Klasse B, freier operator A = B: nur operator A depends on A und B, die Klassen A und B sind aber für sich alleine verwendbar
Was über "operator =" gesagt wurde (modifiziert objekt, braucht lvalue etc.) müsste aber doch auch für +=, -=, /= etc. gelten, oder nicht? Dennoch gibt es die Einschränkung nur für operator =, nicht aber für operator += etc.
Für mich nicht logisch.
-
operator= muss nicht deshalb als member implementiert werden, weil er den linken Operanden modifiziert (und schon gar nicht, weil dieser ein lvalue sein soll - diese Beschränkung besteht ja [leider] gerade nicht).
Möglicherweise steht im D&E etwas dazu, allerdings kann man sich gewichtige Gründe überlegen:
1. wegen des notfall implizit deklarierten Zuweisungsoperators hat jede Klasse diesen Operator. Insbesondere auch Basisklassen - hier ist es zwingend notwendig, das verdeckt wird, andernfalls gehen Sachen wie:struct A {}; struct B : A {}; struct C : A {}; B b; C c; c = b; // geht nicht, denn der Zuweisungsoperator der Basisklasse A wird verdeckt
Das wäre ziemlich schrecklich, und bei der Initialisierung kann das ja nicht passieren. Das führt dann gleich zu
2. Könnte der Zuweisungsoperator als freie Funktion deklariert werden, wäre vorher nie klar, ob er implizit deklariert werden muss. Das hätte den eigenartigen Effekt, dass eine bloße Deklaration die Bedeutung von Code, der davor kommt, im nachhinein noch verändert:
struct A {}; A a,b; a = b; // implizit deklarierter Operator? void operator=(A&, const A&) { cout << "boo"; }
Würden wir verlangen, dass in solchen Fällen der Operator im Moment der ersten Benutzung als deklariert gilt, wäre das eine deutliche Abweichung von der gegenwärtigen Philosophie. Zudem stellt sich die Frage, was passiert, wenn in einer ÜE diese implizite Deklaration stattfindet und in einer anderen nicht. Dann haben wir es genaugenommen mit zwei verschiedenen Klassen zu tun.
Die zusammengesetzten Operatoren implizieren (jedenfalls nach dem Prinzip der geringsten Überaschung) genauso wie die meisten anderen Operatoren Value-Semantik. Das verträgt sich im allgemeinen nicht mit Polymorphie und öffentlicher Vererbung. Dann hat aber immer nur die letzte Ebene der Vererbungshierarchie diese Operatoren und Verdeckung wird unnötig. Implizite Deklaration findet ohnehin nicht statt und damit it gibt es keine technischen Gründe, die gegen eine Implementation als freie Funktion sprechen. Tatsächlich ist es ja so, das eine freie Funktion das Verhalten der eingebauten Operatoren besser imitiert wegen der Beschränkung auf lvalues.
-
Stroustrup schreibt:
If no type conversions are defined, there appears [Hervorhebung von mir] to be no compelling reason to choose a member over a friend taking a reference argument, or vice versa....
All other things considered equal, choose a member. (...) The member function call syntax makes it clear to the user that the object may be modified; a reference argument is far less obvious. Furthermore, expressions in the body of a member can be noticeably shorter than the equivalent expression in a global function; a nonmember function must use an explicit argument, whereas the member can use tis implicitly.[C++PL3, 11.5.2]
-
UBr schrieb:
Stroustrup schreibt:
If no type conversions are defined, there appears [Hervorhebung von mir] to be no compelling reason to choose a member over a friend taking a reference argument, or vice versa....
All other things considered equal, choose a member. (...) The member function call syntax makes it clear to the user that the object may be modified; a reference argument is far less obvious. Furthermore, expressions in the body of a member can be noticeably shorter than the equivalent expression in a global function; a nonmember function must use an explicit argument, whereas the member can use tis implicitly.[C++PL3, 11.5.2]
Ja, offensichtlich eine subjektive Meinung. Ich selbst verwende auch nie 'friend'. Aber darum ging es nicht.
/EDIT: Zumindest hörte sich das nicht so an.