Assignment Operator
-
Hallo.
ich habe eine Frage. Sollte eurer Meinung nach jede Klasse einen Assignment Operator und einen Copy Konstruktor haben? Wozu brauch man die eigentlich? Als Beispiel habe ich hier folgenden Code, bei dem ich erst dachte, man muss einen Assignment Operator nehmen, doch es klappt auch ohne diesen:
class Klasse { public: Klasse(void):VALUE(0){} ~Klasse(void){} void SetVAL (int i) { VALUE = i; } private: int VALUE; }; int main() { Klasse A,B; A.SetVAL(9); B = A; return 0; }
-
Hans Wurst schrieb:
Sollte eurer Meinung nach jede Klasse einen Assignment Operator und einen Copy Konstruktor haben?
jede Klasse HAT einen op= und Copy-Ctor (wenn du selber keinen definierst, erzeugt dir der Compiler einen), also brauchst du im Normalfall keine eigenen
Wozu brauch man die eigentlich?
Du benötigst nur eigene Operatoren, wenn das Default-Verhalten für deine Klasse nicht geeignet ist (das passiert meistens dann, wenn du mit Zeigern operierst und jedes Objekt eine eigene Kopie des Speichers bekommen soll - die Default-Implementation führt eine flache Kopie durch, so daß hinterher alle Beteiligten sich einen Speicherblock teilen müssen).
In dem Zusammenhang gilt auch die "Rule of Three": Copy-Ctor, operator= und Dtor sollten immer zu dritt auftreten (wenn du einen von ihnen brauchst, benötigst du idR alle drei).
Als Beispiel habe ich hier folgenden Code, bei dem ich erst dachte, man muss einen Assignment Operator nehmen, doch es klappt auch ohne diesen:
Ja, hier hast du auch nur einen int-Wert gespeichert, den kann die Default-Version problemlos kopieren.
-
Hans Wurst schrieb:
Sollte eurer Meinung nach jede Klasse einen Assignment Operator und einen Copy Konstruktor haben?
Nach außen hin, nein. Manchmal ist es sinvoll, die Benutzung mittels Verwendung des private-Bereichs zu verbieten. Ansonsten gilt, was CStoll schon gesagt hat.
-
CStoll schrieb:
Hans Wurst schrieb:
Sollte eurer Meinung nach jede Klasse einen Assignment Operator und einen Copy Konstruktor haben?
jede Klasse HAT einen op= und Copy-Ctor (wenn du selber keinen definierst, erzeugt dir der Compiler einen), ...
Hi,
IIRC: ... solange ich selber keinen deklariere, oder ?
Das
class A { A const& operator=(A const&); }; // A::operator=() nicht implementiertsollte doch dazu führen, dass meine Klasse keinen operator=() hat, oder habe ich das falsch verstanden ?
Gruß,
Simon2.
-
Doch, diese Klasse hat einen op= (btw solltest du den korrekten Prototyp verwenden, damit der Compiler das akzeptiert), daß der Linker ihn nicht findet, steht auf einem anderen Blatt.
-
CStoll schrieb:
Doch, diese Klasse hat einen op= (btw solltest du den korrekten Prototyp verwenden, damit der Compiler das akzeptiert), daß der Linker ihn nicht findet, steht auf einem anderen Blatt.
Was heißt in dem Zusammenhang dann "... hat einen operator=() ..." ? Dass es im objectcode der Klasse einen entsprechenden entrypoint gibt ? ....
Gruß,
Simon2.
-
Simon2 schrieb:
Was heißt in dem Zusammenhang dann "... hat einen operator=() ..." ? Dass es im objectcode der Klasse einen entsprechenden entrypoint gibt ? ....
Nein, den gibt es eben nicht. Das führt zu einem Linkerfehler "undefined reference", was landläufig als "ist vergessen worden" interpretiert werden könnte.
Willst Du eine Zuweisung wirkungsvoll unterbinden, mach den op= am besten private und lass die Implementierung weg, dann wirft der Compiler schon Fehler und der Linker brauch sich um den Entry garnicht mehr zu kümmern (da Aufruf garnicht compiliert).
-
CStoll schrieb:
Doch, diese Klasse hat einen op= (btw solltest du den korrekten Prototyp verwenden, damit der Compiler das akzeptiert), daß der Linker ihn nicht findet, steht auf einem anderen Blatt.
Wenn Du das so sehen möchtest, dann hat jede Klasse einen op=. Mehr als private und nicht implementiert geht nunmal nicht.
Da "hat nen op=" und "hat keinen op=" aber so schön einfach sind um drüber zu reden, finde ich man sollte in diesem Fall ruhig sage dürfen, daß die Klasse keinen hat. Das hält die Aussage angenehm kurz und jeder weiß was gemeint ist.
-
Jester schrieb:
CStoll schrieb:
Doch, diese Klasse hat einen op= (btw solltest du den korrekten Prototyp verwenden, damit der Compiler das akzeptiert), daß der Linker ihn nicht findet, steht auf einem anderen Blatt.
Wenn Du das so sehen möchtest, dann hat jede Klasse einen op=.
Sag ich doch

(OK, es gibt ein paar Sonderfälle, wo der Compiler sich weigert, einen op= zu erzeugen)Mehr als private und nicht implementiert geht nunmal nicht.
OK, das ist auch eine Sichtweise - in dem Fall hat die Klasse halt keinen verwertbaren operator=.
-
LordJaxom schrieb:
...was landläufig als "ist vergessen worden" interpretiert werden könnte....
... aber was "vergessen wurde" wird landläufig auch als "ist nicht da" interpretiert; deswegen finde ich die Aussage "Klasse hat keinen" durchaus berechtigt in dem Fall.
Dass Compilefehler immer Linkfehlern vorzuziehen sind (vA für "Fremdnutzer" einer Klasse), ist mir vollkommen klar. Mir geht es nur um die Aussage "Klasse hat immer einen op=; wenn man keinen eigenen definiert, macht der Compiler einen", die ich nicht so richtig finde.
Gruß,
Simon2.
-
Simon2 schrieb:
Mir geht es nur um die Aussage "Klasse hat immer einen op=, wenn man keinen eigenen definiert", die ich nicht so richtig finde (BTW: Wenn man einen eigenen definiert, hat man erst Recht einen
).Das habe ich so nicht gesagt

-
CStoll schrieb:
Simon2 schrieb:
Mir geht es nur um die Aussage "Klasse hat immer einen op=, wenn man keinen eigenen definiert", die ich nicht so richtig finde (BTW: Wenn man einen eigenen definiert, hat man erst Recht einen
).Das habe ich so nicht gesagt

Stimmt - sorry, habe ich korrigiert.
Gruß,
Simon2.