ref, ptr oder shared_ptr
-
- Klasse A benötigt Zugriff auf eine Instanz von B.
- B wird niemals (konzeptionell unmöglich) vor A zerstört.
- A besitzt für die komplette Lebenszeit immer dasselbe B.
Sollte A dann B als eine Referenz, ein Zeiger oder ein shared_ptr besitzen?
? ist ein Platzhalter
class B { }; class A { private: ? member_; public: A(? member); A() = delete; ~A() = default; A& operator=(A const&) = delete; // EDIT A(A const&) = delete; // EDIT }; // ? = B* // ? = B& // ? = std::shared_ptr <B>
-
- Klasse A benötigt Zugriff auf eine Instanz von B.
A braucht demnach irgendeine Art von Verweis auf eine Instanz von B.
- B wird niemals (konzeptionell unmöglich) vor A zerstört.
A wird also immer vor B zerstört. Das heißt, A darf die B-Instanz nicht "besitzen", da es diese nie zerstören wird.
- A besitzt für die komplette Lebenszeit immer dasselbe B.
Der Verweis verändert sich also nicht.
Referenzkonstanter Zeiger.
-
Tim06TR schrieb:
- A besitzt für die komplette Lebenszeit immer dasselbe B.
Bist du sicher? Wäre es nicht sinnvoll, ein swap/operator= anzubieten?
-
reff reff schrieb:
Tim06TR schrieb:
- A besitzt für die komplette Lebenszeit immer dasselbe B.
Bist du sicher? Wäre es nicht sinnvoll, ein swap/operator= anzubieten?
Nach 10 Minuten nachdenken: Das würde vermutlich tausendmal mehr Ärger einhandeln, als es mir nützt.
EDIT: B könnte theoretisch auch ein Singleton sein (was es nicht ist), das würde nichts ändern.
-
Nimm einen Pointer.
-
Wieso keine Referenz?
-
Wieso eine Referenz?
-
Schönere Syntax (keine Dereferenzierungspfeile) und man sagt damit aus, dass das Ding immer zu existieren hat (kein "if (!ptr) ...")?

-
Dobi schrieb:
Schönere Syntax (keine Dereferenzierungspfeile)
Eben nicht! Das Ding ist fremd und soll auch fremd aussehen. Vermeidet Fehler.
Dobi schrieb:
und man sagt damit aus, dass das Ding immer zu existieren hat (kein "if (!ptr) ...")?

Komisch, if(!ptr) mache ich ich bei Zeigern nicht. Wenn der Benutzer Nullzeiger reinsteckt, ist er selber schuld, fertig.
-
volkard schrieb:
Wenn der Benutzer Nullzeiger reinsteckt, ist er selber schuld, fertig.
Kann man nicht in Konstruktor oder setter einfach eine Referenz fordern und dann einfach die Adresse zu nutzen? Wenn man einen Zeiger übergeben kann wirkt das etwas missverständlich.
-
Flashput schrieb:
volkard schrieb:
Wenn der Benutzer Nullzeiger reinsteckt, ist er selber schuld, fertig.
Kann man nicht in Konstruktor oder setter einfach eine Referenz fordern und dann einfach die Adresse zu nutzen? Wenn man einen Zeiger übergeben kann wirkt das etwas missverständlich.
Kann man auch.
Aber dann WIRD bald jemand schreibenB b; return new A(b);während er und jeder andere Leser bei
B b; return new A(&b);sofort merkt, daß da was faul ist.
-
volkard schrieb:
Dobi schrieb:
und man sagt damit aus, dass das Ding immer zu existieren hat (kein "if (!ptr) ...")?

Komisch, if(!ptr) mache ich ich bei Zeigern nicht. Wenn der Benutzer Nullzeiger reinsteckt, ist er selber schuld, fertig.
Ja schon, aber ich dachte auch weniger an den Benutzer sondern an meinen Kollegen, der das Projekt vielleicht irgendwann übernimmt. Ich kann mir vorstellen, dass er bei nem Zeiger vielleicht denkt, dass das Ding auch Null sein könnte, wenn er meinen Kommentar an der Deklaration, der das als verboten beschreibt, nicht direkt liest. Bei einer Referenz hingegen wüsste er sofort Bescheid.
-
Skym0sh0 schrieb:
Wieso keine Referenz?
Weil man Referenzen nicht re-binden kann.
Für noncopyable Objelte war das früher egal. Seit RValue-Referenzen und Move ist es aber auch da ein Thema.
Referenzen sind also nur verwendbar wenn das Objekt noncopyable UND nonmovable sein soll.
-
volkard schrieb:
Kann man auch.
Aber dann WIRD bald jemand schreibenB b; return new A(b);während er und jeder andere Leser bei
B b; return new A(&b);sofort merkt, daß da was faul ist.
Kommt drauf an. Bei
unique_lockübergibt man auch ne Referenz, und ich sehe keine Gefahr dass das jemand falsch versteht.
-
Dobi schrieb:
Ich kann mir vorstellen, dass er bei nem Zeiger vielleicht denkt, dass das Ding auch Null sein könnte, wenn er meinen Kommentar an der Deklaration, der das als verboten beschreibt, nicht direkt liest. Bei einer Referenz hingegen wüsste er sofort Bescheid.
Dann pack ein
assert(ptr);als erste Zeile in den Konstruktor.
-
OK, ihr habt mich überzeugt. Ich hatte nämlich vor Kurzem einen ähnlichen Fall und hab mich für die Referenz entschieden. Hab jetzt aber die Umstellung auf Zeiger auf meine todo-Liste geschrieben.

-
hustbaer schrieb:
Skym0sh0 schrieb:
Wieso keine Referenz?
Weil man Referenzen nicht re-binden kann.
Für noncopyable Objelte war das früher egal. Seit RValue-Referenzen und Move ist es aber auch da ein Thema.
Referenzen sind also nur verwendbar wenn das Objekt noncopyable UND nonmovable sein soll.Vor allem das überzeugt.
