Verschachtelte Klassen
-
hi,
arbeite im mom. an einem kleinen übungsprojekt.
dabei ist bei mir folgende frage aufgekommen :kann ich klassen in einander verschachteln oder ist das unsauber/schlechter stil?
und darf ich von der "inneren/unteren" klasse dann auf die "daten" der "oberen" klasse zugreifen oder wäre das unsauber/schlechter stil?wenn man das so nicht macht wie dann? ( zwei eigenständige klassen mit getter,setter? oder einfach nur 1 klasse wenn ich mich schon soetwas frage...
)
meiner meinung nach wäre wenn ich eine ober und unter klasse habe, das ja nur eine noch stärkere kapselung der daten, da auch die daten der "unteren" klasse aus der "oberen" klasse kommen und gar nicht nach außen gegeben werden müssten.
was sagt ihr dazu?
lg
-
ups, ganz vergessen, wollte noch ein beispiel code-schnipsel posten.
also so meine ich das:
(zur verdeutlichung)class Klasse { private: int priv_data1; int priv_data2; class UntereKlasse { //hier halt jetzt die "untere" klasse und soweiter... }; public: int getter(); int setter(); };
auf diese weise kann ich, die "schnittstelle" ja eig noch genauer definieren und brauche keine unnötigen interna nach außengeben...
jedoch hab ich gehört das dies eine unsaubere lösung sein da ich dann auch von der "unteren" klasse auf die daten der "oberen" zugreifen möchte...
für mich ist das eig eher sauberer da es stärker in einander verkapselt ist und da ich damit eig max 2 ebenen schaffe wirds eig auch nicht verwirrend *finde ich* ...
was sagt ihr dazu?
paar tipps oder ratschläge wären super...
-
Ja, Du kannst Klassen so verschachteln. Ich würde das aber nur ganz selten machen. Die Begriffe Ober- und Unterklasse werden schon bei der Vererbung verwendet. Hier würde ich eher von innerer und äußerer Klasse reden. Die innere Klasse hat keinen automatischen Zugriff auf die Elemente der äußeren Klasse.
Die innere Klasse macht meistens nur Sinn, wenn es sich um eine kleine Hilfsklasse, mit ganz wenig Funktionaltät, die wirklich nur hier gebraucht wird, handelt.
Das kann man aber oft auch anders lösen. Z.B. indem man die Hilfsklasse nur in der cpp-Datei für die Hauptklasse in einem anonymen Namespace definiert. Dann sind die Klassen nicht verschachtelt und die Hilfsklasse ist trotzdem für alle anderen nicht sichtbar.
-
Das ist möglich und üblich. Ob es in deinem speziellen Fall sauber wäre ist nicht zu sagen, weil du keinen konkreten Anwendungsfall beschreibst.
Die innere Klasse verhält sich quasi wie ein Friend der äußeren und hat daher vollen Zugriff.
-
DJohn schrieb:
Ja, Du kannst Klassen so verschachteln. Ich würde das aber nur ganz selten machen. Die Begriffe Ober- und Unterklasse werden schon bei der Vererbung verwendet. Hier würde ich eher von innerer und äußerer Klasse reden. Die innere Klasse hat keinen automatischen Zugriff auf die Elemente der äußeren Klasse.
Die innere Klasse macht meistens nur Sinn, wenn es sich um eine kleine Hilfsklasse, mit ganz wenig Funktionaltät, die wirklich nur hier gebraucht wird, handelt.
Das kann man aber oft auch anders lösen. Z.B. indem man die Hilfsklasse nur in der cpp-Datei für die Hauptklasse in einem anonymen Namespace definiert. Dann sind die Klassen nicht verschachtelt und die Hilfsklasse ist trotzdem für alle anderen nicht sichtbar.
Stimmt vielen Dank für den Hinweis
, das mit einem anonymen Namespace zu lösen ist eine super Idee.
Glaube so werde ich es machen...
Vielen Dank.
-
SeppJ schrieb:
Das ist möglich und üblich. Ob es in deinem speziellen Fall sauber wäre ist nicht zu sagen, weil du keinen konkreten Anwendungsfall beschreibst.
Die innere Klasse verhält sich quasi wie ein Friend der äußeren und hat daher vollen Zugriff.
Ok, ich habe eine "äußere" Klasse die Daten sammelt und eine "innere" Klasse die diese dann weiterverarbeitet und ausgibt
.
Dazu brauche ich vollen Zugriff auf die "äußere" Klasse.
Es ist aber nicht nötig die "innere" Klasse, nach "außen" hin zu zeigen.
Also könnte ich das da auch so lassen?Jetzt bin ich verunsichert
.
Wann würde es denn Sinn machen ?
-
DummyFrage schrieb:
Ok, ich habe eine "äußere" Klasse die Daten sammelt und eine "innere" Klasse die diese dann weiterverarbeitet und ausgibt
.
Das klingt eher nach einem Falls für zwei vollkommen unabhängige Klassen.
Jetzt bin ich verunsichert
.
Wann würde es denn Sinn machen ?Wenn es eben einen Datentyp gibt, der mit der äußeren Klasse fest assoziiert ist, aber dessen Instanzen auch unabhängig von diesem existieren können. Ein typisches Beispiels wäre ein Iterator für einen Container.
-
Die innere Klasse verhält sich quasi wie ein Friend der äußeren und hat daher vollen Zugriff.
Keine Ahnung ob ich grad den Kontext misse, aber pauschal ist das schlicht falsch. (Siehe §9.7/4)
-
Arcoth schrieb:
Die innere Klasse verhält sich quasi wie ein Friend der äußeren und hat daher vollen Zugriff.
Keine Ahnung ob ich grad den Kontext misse, aber pauschal ist das schlicht falsch. (Siehe §9.7/4)
Lies noch mal genau:
Like a member function, a friend function (11.3) defined within a nested class is in the lexical scope of that
class; it obeys the same rules for name binding as a static member function of that class (9.4), but it has no
special access rights to members of an enclosing class.Es geht nicht um die Member der Klasse, sondern deren friends. Also bloß die Klarstellung, dass der alte Grundsatz "die Freunde meiner Freunde sind nicht (unbedingt) meine Freunde" auch hier gilt.
Dies hingegen geht wunderbar, wie aus §9.7/1 (indirekt) hervor geht:
class outer { private: int foo; class inner { void func(outer o) { o.foo = 5; } }; };
-
ich habe es gerade getested (VS2012). Die innere Klasse kann tatsächlich auf private Member der äußeren zugreifen. Nach einem kurzem Googlen sieht es so aus, als wäre da der Standard mal angepasst worden, um Zeideutigekeiten bei der Auslegung auszuschließen. Da hab ich wohl was verpasst.
-
Scheint wohl so zu sein, meine Schuld.
-
Wann würde es denn Sinn machen ?
Wenn es eben einen Datentyp gibt, der mit der äußeren Klasse fest assoziiert ist, aber dessen Instanzen auch unabhängig von diesem existieren können. Ein typisches Beispiels wäre ein Iterator für einen Container.
ok.
ich habe in der "äußeren" klasse ein filehandle auf eine datei.
dieses muss ich aber "offen" halten und live die daten verarbeiten und ausgeben mit der zweiten "inneren" Klasse.außerdem entspricht die "innere" klasse eher nur einer "kleinen" helferklasse die nur kleine sachen(hilfs dienste der "äußeren") macht.
dachte ich hab mal gelesen das man das so nutzen kann, vll verwechsel ich das auch...die "äußere" klasse muss aber nach "außen" hin , nur soetwas wie "openhandle", "
ausgabe der daten" und "beenden" zeigen.
worüber dann alles "gesteuert" wird...wäre das nicht so ein fall?
wie würdet ihr mir empfehlen dies zu lösen?
oder verfolge ich hier den falschen ansatz und sollte ich eher direkt zwei getrennte klassen nutzen?vielen dank für alle antworten und hinweise.
lg
-
Du beschreibst Funktion, wenn du deine Klassen beschreibst. Dabei ist doch bei der Beschreibung einer Klasse viel wichtiger, was Objekte dieser Klasse darstellen, nicht deren Funktion. Funktion ist etwas für Funktionen
. Dies kann auch Teil einer Klasse sein, aber zentraler Aspekt einer Klasse ist immer noch, dass sie Objekte beschreibt.
Die einzige Beschreibung eines Objekts, die du benutzt, ist "Filehandle" und das ist anscheinend eine fremde Klasse, die du benutzt.
Ich könnte mir anhand deiner Beschreibung gut vorstellen, dass dein Klassendesign nichts taugt. Man kann zwar Klassen von der Art
class Mülleimerausleerung; Mülleimerausleerung my_mülleinmerausleerung; my_mülleinmerausleerung.execute();
machen, aber das ist sehr javaesque. Klassen sollten Objekte unserer Vorstellungskraft beschreiben, keine Vorgänge.
-
SeppJ schrieb:
Du beschreibst Funktion, wenn du deine Klassen beschreibst. Dabei ist doch bei der Beschreibung einer Klasse viel wichtiger, was Objekte dieser Klasse darstellen, nicht deren Funktion. Funktion ist etwas für Funktionen
. Dies kann auch Teil einer Klasse sein, aber zentraler Aspekt einer Klasse ist immer noch, dass sie Objekte beschreibt.
Die einzige Beschreibung eines Objekts, die du benutzt, ist "Filehandle" und das ist anscheinend eine fremde Klasse, die du benutzt.
Ich könnte mir anhand deiner Beschreibung gut vorstellen, dass dein Klassendesign nichts taugt. Man kann zwar Klassen von der Art
class Mülleimerausleerung; Mülleimerausleerung my_mülleinmerausleerung; my_mülleinmerausleerung.execute();
machen, aber das ist sehr javaesque. Klassen sollten Objekte unserer Vorstellungskraft beschreiben, keine Vorgänge.
ok entschuldigt, wie meinst du daten genau? meine daten struktur oder die daten die ich abfrage?
meine datenstruktur ist ungefähr so, bzw. hatte ich mir das so vorgestellt:
class A { private: struct data_a; struct data_b; class B // hier sind nun die daten & funktionen die in der "verarbeitung_der_daten();" gebraucht werden { private: struct data_c; struct data_d; struct data_e; struct data_f; public: int erkenne_data(); int formatierung_data(); int ausgabe_data(); }; public: int start(startparameter); int verarbeitung_der_daten(); int stop(); };
als erstes werden daten in klasse "A", struct "a,b" geladen zum öffnen des handles,danach werden diese nicht mehr gebraucht.
dann sammelt die funktionen der klasse "A" daten aus meiner datei und "übergibt" diese einer funktion der klasse "B" diese verarbeitet die und speichert sie in struct "c,d,e,f".
die daten in der struct "c,d,e,f" werden dann so wie sie sind ausgegeben.
es ist aber nicht nötig das klasse "B" ohne die klasse "A" existiert weil eig Klasse "A", die Klasse "B" ja nur benutz / daten speichert.
deswegen hab ich so die schritte nochmal getrennt.
da hab ich gedacht so wäre das am ersichtlichsten für jemand der da nochmal drüber schaut.bzw. könnte ich so die klasse "B" auch gut in einem anderen code von mir nochmal verwenden ...
könnte ich das dann so machen?
oder sollte ich lieber beide klassen voneinander trennen ?
dann getter setter methoden schreiben die die daten "übergeben" ?wäre das von mir beschriebene, ein schlechtes design?
warum? wie könnte man das besser lösen und warum? -> links würden mir auch schon helfen ich lese gern
will euch hier ja auch kein ohr abkauen...
vielen dank nochmal für die hilfe
-
Hat sich erledigt...
Habs komplett in zwei Klassen getrennt.
Problem gelöst.
Vielen Dank für die Hilfe und Hinweise.
lg