Wo gehören die Objekte hin?
-
Hallo. Eine Designfrage.
Scott Meyers sagt. Gebe keine Referenzen auf die internen Daten eines Objektes aus. Das schwächt die Kapselung. Schön und gut. Versteh ich auch.
Nun zur Praxis und zu meinem Konkreten Problem.
Ich habe eine Klasse virtual_machine_t. Diese beötigt zugriff auf ein Objekt der des typs return_stack_t um funktionieren zu können. Naheliegend also erst einmal den Stapel als privaten member anzugeben. Jetzt soll aber auf diesen Stapel, genauer die gleiche Instanz, von anderen Objekten aus von außen aus zugegriffen werden. Jetzt stellt sich mir die Frage ob ich eine Referenz auf den Stapel zurückgeben soll, oder eine Referenz auf den Stapel als Übergabeparameter für die Konstruktion von virtual_machine_t verlange. Die Konstruktion des Stapels sozusagen in die Hände des Benutzers der Klasse lege.
Welchen Weg würdet ihr gehen und warum. Beide Wege scheinen mir plausibel zu sein.Danke,
Martin
-
das ist doch schon nicht ganz koscher. wenn 2 klassen auf einen member zugreifen müssen sind sie ja schon nicht unabhängig.
was hast du denn vor, kannst du deinen fall auf ein minimales beispiel runterbrechen?ansonsten kapselung beibehalten und kopien per methode hin- und herreichen
also per getter und setter und gleichzeitig sorgen diese methoden für konsistenz innerhalb der datenstrukturedit: oder zur not zeiger. also z.b. einen shared_ptr<DEINE_LISTE> als member von beiden
-
Meinst du bei Stapel einen Container/Collection? Bei diesen Objekttypen sagt Meyers aber auch, das es eine Ausnahme gibt: man darf und kann nur direkt darauf zugreifen. vector, list u.a. machen es vor.
Ansonst, wenn sich der Stapel in einem Objekt befindet, wirst du natürlich kapseln müssen.
class A { stapel m_stapel; };Darf man nicht auf m_stapel direkt zugreifen! Aber du kannst auf s einen getter und setter schreiben.
class A { stapel m_stapel; public: stapel get_stapel() const { return m_stapel; } void set_stapel(const stapel &s) { m_stapel = s; } };Jeder schlaue Compiler wird z.B. beim Aufruf des getters schauen, ob er sich das Kopieren sparen kann, selbst wenn es keine Reference ist, die zurück kommt.
Wenn was kopiert wird, haste Pech.
Aber, du kannst das ganze minimieren:
class A { stapel<B> m_stapel; public: B pop() const { return m_stapel.pop(); } void push(B &b) { m_stapel.push(b); } stapel<B> get_stapel() const { return m_stapel; } void set_stapel(const stapel<B> &s) { m_stapel = s; } };Bei der Kapselung muß man einfach den langfristigen Vorteil sehen: die Wartung des Codes wird einfacher. Und man muß etwas Performance verzichten und hoffen, das der Compiler was optimiert.
-
OK. Danke schön. Hab das Problem gelöst. virtual_machine_t ist im Besitz der Objekte. Diese sind privat und werden über Methoden der virtual_machine_t Schnitstelle manipuliert. Keine Referenzen werden somit nach außen gegeben. Dein letztes Codebeispiel hat mich in die richtige Richtung gelenkt.

Das nächste Problem wartet allerdings schon.
