Operatoren überladen (=)
-
... und der übergebene Parameter sollte keine Kopie sein! Und der copy-ctor fehlt auch.
class POLY { ... POLY(const POLY& rhs) { ... } POLY& operator=(const POLY& rhs) { ... return *this; } ... }
Wenn man auf Selbstzuweisung aus einem anderen Grund prüfen muss, als sich überflüssige und möglicherweise kostspielige Anweisungen zu sparen, dann hat man oft ein anderes Problem: Der Code ist dann in vielen Fällen nicht Exception-sicher! Wenn man erst den Speicher löscht und new eine Exception auslöst, steht man dumm da - Der Zeiger zeigt jetzt auf ungültige Daten und spätestens im Konstruktor kracht's. Die Lösung mit swap ist besser
-
Shade Of Mine schrieb:
... so implementiert man swap, welches die zeiger tauscht und laesst den copyctor die ganze arbeit uebernehmen.
kannst mir mal erklären wie du das meinst mit swap? unter swap verstehe ich tauschen aber bei einer zuweisung geht es nicht um tauschen sondern um kopieren. rechtes Objekt übergibt Daten ans linke Objekt ohne selbst verändert zu werden.
wo ist mein fehler?
-
Beim auto-ptr Smart-Pointer wird getauscht statt zugewiesen, ich finde die Überladung aber sowieso nicht sonderlich schön, weil der Parameter, wie schon gesagt, eine Referenz sein sollte, oder?
-
otze schrieb:
im fall von referenzen ist das eher schlampig,oder fällt dir eine situation ein, in der es vom programmiertechnischen her unmöglich ist zu verhindern, dass eine selbstzuweisung überhaupt stattfinden kann?(unter der vorraussetzung natürlich, dass man seinen code anständig kommentiert und sauber aufgebaut hat)
- habe ich quasi nie kommentare im quellcode - wozu auch?
- programmiere ich sicher nicht schlampig
- man _kann_ es vermeiden, nur warum sollte ich es immer vermeiden wollen?
wenn es einfacher ist diese selbstzuweisung uU in kauf zu nehmen als sie explizit abzufangen. - if in doubt, do as the ints do
desweiteren mach ich persönlich nen bogen um assert solange es kein fehler ist,der verhindert, dass mein programm noch weiterlaufen kann,
Das ist ein fehler deinerseits.
assert ist fuer _alle_ logikfehler.im falle von selbstzuweisungen reicht auch ne exception(obwohl es ein logikfehler ist, die programmlogik ist halt fehlerhaft,da sie das nicht automatisch verhindern konnte).
eine exception wuerde heissen, dass du auf diese situation reagieren kannst: wie denn?
-
Hallo,
Shade Of Mine schrieb:
- habe ich quasi nie kommentare im quellcode - wozu auch?
vielleicht (nur) deshalb, damit auch andere Entwickler deinen Code leichter und schneller verstehen und sich in diesen einarbeiten können, falls der Code "in andere Hände" gerät?
Oder um Tools einzusetzen, die aus Kommentaren Dokus erzeugen können ?
Oder du hast einen so exzellenten coding style, der keinerlei Kommentare bedarf :), dann Glückwunsch.
Ich gebe allerdings zu, daß auch bei mir Kommentare öfter zu kurz kommen, dies liegt aber eher an den in Projekten einzuhaltenden Terminen.
Zum Thema: in den anderen Anmerkungen stimme ich überein, ein assert ist durchaus angebracht, auf das Werfen irgendwelcher exceptions würde ich hier (Selbstzuweisung) nicht einmal im Traum kommen (müßten schon sehr schlechte Träume sein
)
MfG
-
Online schrieb:
rechtes Objekt übergibt Daten ans linke Objekt ohne selbst verändert zu werden.
wo ist mein fehler?genau das passiert doch mit shades op=
schau ihn dir nochmal genau an.
-
Probe-Nutzer schrieb:
vielleicht (nur) deshalb, damit auch andere Entwickler deinen Code leichter und schneller verstehen und sich in diesen einarbeiten können, falls der Code "in andere Hände" gerät?
Warum sollte ich zB folgendes kommentieren:
template<class Policy> class Timer { public: typedef typename Policy::value_type value_type; private: value_type value; public: Timer() { Policy::now(value); } value_type elapsed() const { return Policy::elapsed(value); } };
wo passen da kommentare hin?
Oder um Tools einzusetzen, die aus Kommentaren Dokus erzeugen können ?
das ist n gutes argument - brauch ich aber nur wenn ich eine library schreibe.
Oder du hast einen so exzellenten coding style, der keinerlei Kommentare bedarf :), dann Glückwunsch.
sobald ich einen kommentar brauche um den code zu verstehen, schreibe ich ihn um.
in der arbeit geht das zwar nicht - aber dort gibt es auch keine doku oder aehnliches :p
-
davie schrieb:
Online schrieb:
rechtes Objekt übergibt Daten ans linke Objekt ohne selbst verändert zu werden.
wo ist mein fehler?genau das passiert doch mit shades op=
schau ihn dir nochmal genau an.also ich weis jetzt nicht wie die Funktion swap aussehen soll aber ich stelle mir da sowas vor...
swap( klasse i) { klasse puffer; puffer.a = this->a; this->a = i.a; i.a = puffer.a; //usw.... }
das tauschen wie es im "Duden" definiert ist A bekommt alles von B und B bekommt alles von A
ich versteh nicht wie das mit dem Zuweisungsoperator zutun hat
-
Online schrieb:
also ich weis jetzt nicht wie die Funktion swap aussehen soll aber ich stelle mir da sowas vor...
habe ich doch gesagt: es tauscht die zeiger:
void swap(klasse& other) { std::swap(a, other.a); std::swap(b, other.b); }
Funktioniert sehr gut wenn a und b nur primitive typen sind, oder selber std::swap spezialisiert haben
das tauschen wie es im "Duden" definiert ist A bekommt alles von B und B bekommt alles von A
ich versteh nicht wie das mit dem Zuweisungsoperator zutun hatZuweisung ist: copy and swap
du erstellst per CopyCtor eine Kopie und tauscht diese kopie dann mit dem objekt dem du den wert zuweisen willst aus.der vorteil liegt auf der hand: extrem wenig code, exceptionsicher und nicht wirklich langsamer als ein herkoemmlicher op= (merzt aber _alle_ fehlerquellen aus)
-
desweiteren mach ich persönlich nen bogen um assert solange es kein fehler ist,der verhindert, dass mein programm noch weiterlaufen kann,
Das ist ein fehler deinerseits.
assert ist fuer _alle_ logikfehler.ja super, was bringt mir das? im zweifesfall starte ich das programm, und das kickt mich sofort beim kleinsten logischen fehler.
assert ist mir zu extrem, ich will auf ne selbstzweisung aufmerksam gemacht werden,zb halt durch ne exception, die abgefangen wird und dann in irgendeine debug box schreibt: achtung selbstzuweisung in datei xxx.txt zeile 16 funktion xxx(parameter1,parameter2,parameter3)
-
otze schrieb:
ja super, was bringt mir das? im zweifesfall starte ich das programm, und das kickt mich sofort beim kleinsten logischen fehler.
assert ist mir zu extrem, ich will auf ne selbstzweisung aufmerksam gemacht werden,zb halt durch ne exception, die abgefangen wird und dann in irgendeine debug box schreibt: achtung selbstzuweisung in datei xxx.txt zeile 16 funktion xxx(parameter1,parameter2,parameter3)interessant - das programm kann dann normal weiterlaufen? eine zuweisung ist fehlgeschlagen, bei mir ist das meistens dann ein kritischer fehler...
naja, aber inwiefern ist es besser eine exception zu werfen und dann eine textbox auszugeben (btw: wo faengst du die denn dann ab??) als ein feines assert, dass die selbse ausgabe macht?
wobei selsbtzuweisung _keine_ Fehler ist.
ich habe genug argumente genannt.
-
wer sagt, dass ich die zuweisung fehl schlagen lasse? ich setz halt nur zusätzlich ne exception,der programmierer wird davon in kenntnis gesetzt und das programm läuft danach normal weiter.
wobei selsbtzuweisung _keine_ Fehler ist.
ich habe genug argumente genannt.meinst du das argument, wo du sagst, dass du die selbstzuweisung in kauf nimmst oder das,wo du sagst, dass es einfacher ist,im operator eine selbstzuweisung abzufangen?
naja, aber inwiefern ist es besser eine exception zu werfen und dann eine textbox auszugeben (btw: wo faengst du die denn dann ab??) als ein feines assert, dass die selbse ausgabe macht?
da ich normalerweise nur grafikanwendungen schreibe, ist mir klar, wo ich diese exception abfange: in einem catchblock in der main, welcher sich der DebugExceptionHandling Class bedient(rendert ganz am schluss eines programmschleifendurchgangs eine infobox mit etwaigen fehlermeldungen oben rechts in die ecke)
-
otze schrieb:
wer sagt, dass ich die zuweisung fehl schlagen lasse? ich setz halt nur zusätzlich ne exception,der programmierer wird davon in kenntnis gesetzt und das programm läuft danach normal weiter.
Wie geht das?
a=b;
cout<<a;wie wird cout<<a ausgefuehrt, wenn a=b eine exception wirft?
meinst du das argument, wo du sagst, dass du die selbstzuweisung in kauf nimmst oder das,wo du sagst, dass es einfacher ist,im operator eine selbstzuweisung abzufangen?
und was ist mit "do as the ints do"?
wie waere es mit:
bool fill(T& obj, foo kriterium) { iterator i=find(kriterium); //aus irgendeiner liste oder aehnliches laden if(i!=end) { obj=*i; return true; } return false; }
wenn ich da das naechste mal wieder das selbe objekt bekomme, dann ist das doch kein fehler, oder? es ist mir ja egal was vorher in obj drinnen stand...
da ich normalerweise nur grafikanwendungen schreibe, ist mir klar, wo ich diese exception abfange: in einem catchblock in der main, welcher sich der DebugExceptionHandling Class bedient(rendert ganz am schluss eines programmschleifendurchgangs eine infobox mit etwaigen fehlermeldungen oben rechts in die ecke)
und dann laeuft die anwendung ganz normal weiter? der ganze durchlauf wird doch durch die exception abgebrochen...
-
Hallo.
Habe den Quelltext nochmal verändert. Das Programm läuft soweit zufriedenstellend, will heissen es ist der Aufgabenstellung gerecht geworden. Auch wenn ich nicht alle Antworten recht zuordnen kann, habe ich versucht das Beste draus zu machen.
Würde mich über weitere Kommentare freuen.
Gruß,
Johrtreel
-
Shade Of Mine schrieb:
Warum sollte ich zB folgendes kommentieren:
template<class Policy> class Timer { public: typedef typename Policy::value_type value_type; private: value_type value; public: Timer() { Policy::now(value); } value_type elapsed() const { return Policy::elapsed(value); } };
sollst du, von mir aus zumindest, auch gar nicht, denn da hast du ein Paradebeispiel angegeben, bei dem auch ich mich schwer tun würde, etwas zu kommentieren (nein, nicht weil ich den Code nicht verstehe)
Ich hatte aber schon Chefs/Projektleiter, die auch dort gerne Kommentare gesehen hätten (na gut, ich gebe zu, etwas komplexer war die Klasse schon, aber für mich nur unwesentlich), es gibt nichts, was es nicht gibt.
Shade Of Mine schrieb:
wo passen da kommentare hin?
in die Leerzeilen z.B., SCNR
Oder um Tools einzusetzen, die aus Kommentaren Dokus erzeugen können ?
Shade Of Mine schrieb:
das ist n gutes argument - brauch ich aber nur wenn ich eine library schreibe.
du Glücklicher, manchmal kann man es sich nicht aussuchen, siehe oben
Shade Of Mine schrieb:
sobald ich einen kommentar brauche um den code zu verstehen, schreibe ich ihn um.
in der arbeit geht das zwar nicht - aber dort gibt es auch keine doku oder aehnliches :p
in den wenigsten Fällen schreibe ich Kommentare für mich (wenn man mal von so Dingen wie /* TO DO */ oder ähnlichem absieht), es geht ja nicht um "Selbstbeweihräucherung" des Codes oder um eine besonders schöne Verpackung des Codes in Kommentaren. Auch verliert die Kommentierung an Bedeutung für einen selbst, wenn man schon eine gewisse "Klasse" in der Programmierung erreicht hat, es geht, wie ich schon angedeutet habe, oft um externe oder interne Vorgaben (oder um "Weitsicht", wenn man weiß, daß der Code bald von anderen zur Pflege/Weiterentwicklung übernommen wird, und man nicht unbedingt von den Fragen des "Nachfolge-Entwicklers" genervt werden will
)
MfG
-
Wenn eine Methode nicht gerade getSize() oder distanceTo(const Point&) heisst, setze ich da eigentlich schon immer nen Satz drüber.