Iterator
-
Hab selber gar was gefunden.
Der zuweisungsoperator muss keinen Speicher anfordern.
Beim Copy Konstruktor hingegen existiert noch kein Speicher, da das
Objekt erst angelegt wird.
-
Blackskyliner schrieb:
Huch, da wahr ich wohl etwas zu übereifrig mit implementieren

Aber ist es nicht eigentlich egal, wenn man den copy private setzt?
Ist es insofern unerwünscht, damit man IN der Singleton nicht versehentlich kopiert?wieso sollte man etwas (falsch) implementieren, wenn man es doch gar nicht braucht? so gar: wenn man verhindern will, dass es verwendet wird.
üblicherweise setzt man so gar noch den assignment-operator private (und auch hier implementiert man nichts). ist zwar in meinen augen überflüssig, aber schaden kann auch das nicht.bb
-
blurry333 schrieb:
Hab selber gar was gefunden.
Der zuweisungsoperator muss keinen Speicher anfordern.
Beim Copy Konstruktor hingegen existiert noch kein Speicher, da das
Objekt erst angelegt wird.von der sache her richtig - allerdings würde ich es eher anders formulieren.
beim =operator muss zuerst das alte objekt zerstört werden und dann kann erst das neue konstruiert werden. (die reihenfolge wird aber oftmals nicht eingehalten, weil er durch das copy-and-swap-idiom(->google) exceptionsicher gemacht werden kann, man keine code-duplizierungen hat und wenn überhaupt allenfalls minimal messbare performance-unterschiede entstehen.
aber wie schon gesagt, solltest du hier weder copyctor noch assignment-op implementieren, sondern einfach nur als private deklarieren.bb
-
muss man nicht eigentlich auch noch operator=() überladen? <kram code raus>
class Single{ private: Single(){}; // can not be called Single(Single const&){}; // can not be copyed Single& operator=(Single const&){}; // can not be reassigned public: static Single* getInstance(); // ... methods that make sense ... private: static Single* singled; }; Single* Single::singled = NULL; Single * Single::getInstance() { if (! singled) singled = new Single(); return singled; }
-
hab ich doch gerade schon geschrieben...
padreigh schrieb:
class Single{ private: /* Single(){}; // can not be called Single(Single const&){}; //NEIN! Single& operator=(Single const&){}; //NEIN! */ Single() {} Single(const Single&); //LNK error if called Single& operator=(const Single&); //LNK error if called public: static Single* getInstance(); // ... methods that make sense ... private: static Single* singled; }; Single* Single::singled = NULL; Single * Single::getInstance() { if (! singled) singled = new Single(); return singled; }Nachteil an dieser Lsg. ist, dass sie nicht thread-safe ist.
die static-Methode ist wenigstens im GCC thread-safe. im msvc glaube ich aber (noch?) nicht.bb
-
unskilled schrieb:
[...]von der sache her richtig - allerdings würde ich es eher anders formulieren.
beim =operator muss zuerst das alte objekt zerstört werden und dann kann erst das neue konstruiert werden.[...]Wieso das denn?
-
Tachyon schrieb:
unskilled schrieb:
[...]von der sache her richtig - allerdings würde ich es eher anders formulieren.
beim =operator muss zuerst das alte objekt zerstört werden und dann kann erst das neue konstruiert werden.[...]Wieso das denn?
Mit "altes Objekt" ist das Objekt gemeint, dem ein neuer Wert zugewiesen werden soll. Z.B. muss ein vector in seinem op= zuerst seine alten Elemente freigeben, bevor er die neuen kopieren kann. Im Copy-Ctor entfällt das, da es keine alten Elemente gibt.
-
Tachyon schrieb:
unskilled schrieb:
[...]von der sache her richtig - allerdings würde ich es eher anders formulieren.
beim =operator muss zuerst das alte objekt zerstört werden und dann kann erst das neue konstruiert werden.[...]Wieso das denn?
weil
Der zuweisungsoperator muss keinen Speicher anfordern.
Beim Copy Konstruktor hingegen existiert noch kein Speicher, da das
Objekt erst angelegt wird.der zuweisungsoperator muss sehr wohl (unter umständen) speicher anfordern.
beim eintritt in den copyctor existiert der speicher genau genommen schon und er muss nur noch initialisiert werden.bb
-
ipsec schrieb:
Z.B. muss ein vector in seinem op= zuerst seine alten Elemente freigeben, bevor er die neuen kopieren kann.
Nein. Das wäre ganz schlecht im Bezug auf Exceptionsicherheit.
unskilled schrieb:
beim eintritt in den copyctor existiert der speicher genau genommen schon und er muss nur noch initialisiert werden.
Woher kommt der bereits existierende Speicher, wenn er nicht im Kopierkonstruktor angefordert werden muss?
-
Nexus schrieb:
ipsec schrieb:
Z.B. muss ein vector in seinem op= zuerst seine alten Elemente freigeben, bevor er die neuen kopieren kann.
Nein. Das wäre ganz schlecht im Bezug auf Exceptionsicherheit.
Ich meinte das anschaulich: beim op= gibt es noch Elemente, um die sich irgendwie gekümmert werden muss, beim CopyCtor nicht. Wie jetzt die konkrete Implementierung aussieht, weiß ich nicht.
-
ipsec schrieb:
Ich meinte das anschaulich: beim op= gibt es noch Elemente, um die sich irgendwie gekümmert werden muss, beim CopyCtor nicht.
Okay. Ich würde nur generell von dem Schema wegkommen, dass bei einer Zuweisung zuerst der alte Wert zerstört und dann der neue neu konstruiert werden muss. Bei komplexeren Implementierungen geschieht das oft umgekehrt, um im Fehlerfall keine Zombie-Objekte zu haben.
Denk dran, dass bei solch schematischen Implementierungen bereits sowas einen schwerwiegenden Fehler darstellt. Und das darf nicht sein. Eine explizite Abfrage im
operator=löst das Gesamtproblem übrigens auch nur bedingt.MyClass a; a = a;ipsec schrieb:
Wie jetzt die konkrete Implementierung aussieht, weiß ich nicht.
Schau dir mal das Copy-and-Swap-Idiom an. Damit kannst du neben allen anderen Vorteilen auch Codeduplizierung vermeiden, indem du im Zuweisungsoperator den Kopierkonstruktor verwendest.
-
Sicher, dass
vectorauf copy-and-swap setzt? Ich meine gehört zu haben, dass der zusätzliche temporäre Speicherplatz in der Größe des zu kopierenden vectors mit der Designphilosophie der Standardbibliothek unvereinbar ist.
-
Nein, ich bin mir nicht sicher, ich meinte den Absatz mit Copy-and-Swap eher allgemein. Möglicherweise wird bei
std::vector::operator=nur die schwache Exception-Garantie durchgesetzt, wie beistd::copy(). Aber zumindest beim Vergrössern könnte die starke Garantie genutzt werden.Ich wollte vor allem sagen, dass der
std::vectorden Speicherplatz der alten Objekten keinesfalls freigeben muss, wie du es geschrieben hast.Container sind hier sowieso etwas speziell, weil ihre Instanzen unterschiedlich viel Speicherplatz verwenden. Daher kann Copy-and-Swap performancemässig nicht so der Hit sein, da hast du völlig Recht. Sonst ist es allerdings oft ein sinnvolles Idiom.