Forum: PC-Programmierung C++: Objektinstanzen global nutzen


von derjenigewelcher (Gast)


Lesenswert?

Moin moin,

Ich weiß nicht, ob ich grad einen Knick im Kopf habe, jedenfalls will 
mir kein rechter Weg für mein Problem einfallen:

In einem C++-Projekt erzeuge ich mir in einer Instanz von Klasse A (Ein 
Fenster) Objekte von Klasse B. Auf diese möchte ich eigentlich auch 
gerne in einer Instanz von Klasse C (Ein anderes Fenster) zugreifen.

Wie bewerkstellige ich das am besten? Oder ist es totaler Humbug ;)?

Gruß, djw.

von P. S. (Gast)


Lesenswert?

Wie waer's mit einer Methode getB() in A?

von Rene H. (Gast)


Lesenswert?

Mit einer Klassenmethode
1
instance(void);

Guck mal nach Singleton Pattern.

von Karl H. (kbuchegg)


Lesenswert?

derjenigewelcher schrieb:

> In einem C++-Projekt erzeuge ich mir in einer Instanz von Klasse A (Ein
> Fenster) Objekte von Klasse B. Auf diese möchte ich eigentlich auch
> gerne in einer Instanz von Klasse C (Ein anderes Fenster) zugreifen.
>
> Wie bewerkstellige ich das am besten? Oder ist es totaler Humbug ;)?

Es gibt da mehrere Lösungen.
Kannst du mal die Dinge etwas konkreter benennen.

Eventuell ist nämlich auch eine ganz normale Document-View Struktur die 
Lösung für dein Problem.

Das Document hält Daten.
Das Document hat auch einen Satz von Views (=Fenster), welche die Daten 
anzeigen (unter Umständen auf verschiedene Art und Weise)

Ein View erzeugt selbst keine Daten, sondern er beauftragt das Document 
dies zu tun. Hat das Document die Daten erzeugt, so benachrichtigt es 
alle Views, dass sich die Daten verändert haben, und die Views erzeugen 
eine neue Visualisierung der Daten.

   Document  =   Container, der die Daten hält und manipuliert
   View      =   Anzeigeklasse, die die Daten in einer bestimmten
                 Art und Weise visualisiert.

von derjenigewelcher (Gast)


Lesenswert?

Das klingt gar nicht mal schlecht... Was mir natürlich ein Begriff ist, 
ist die Trennung in Model - View - Controller, das ist ja vermutlich als 
äquivalent zu deinem Post zu verstehen (Model = Document). Daran hatte 
ich eigentlich auch versucht mich zu halten und mich entsprechend daran 
gestört, dass ich die Trennung nicht wirklich sauber hingekriegt habe.

Vereinfacht erklärt braucht meine erste View ("Klasse A") Beschriftungen 
für ihre Buttons. Aus diesem Grund legt sie Objekte einer zweiten Klasse 
an ("Klasse B"), deren Attribut xy die Beschriftung ergibt.

Betätige ich z.B. einen dieser Buttons, öffnet sich eine zweite View 
("Klasse C"), aus der heraus ich die Objekte von "Klasse B" verändern 
können möchte (AUCH Atrribut xy, welches idealerweise beim zurückkehren 
zur ersten View aktualisiert ist).

Wie gesagt: MVC ist mir ein Begriff - und auch, dass ich es wohl falsch 
geamcht habe, wenn meine View Objekte = Daten erstellt. Zumal ich den 
"Inhalt" dieser Objekte ohnehin in erster Linie an anderer Stelle - und 
nicht hauptsächlich zur Erzeugung der Beschriftung - nutzen möchte...

Ich weiß nur nicht, wie ich diese Trennung sauber hinkriege. Brauche ich 
eine zusätzliche Klasse, die rein für die "Vermittlung" zuständig ist?

von Karl H. (kbuchegg)


Lesenswert?

derjenigewelcher schrieb:

> Vereinfacht erklärt braucht meine erste View ("Klasse A") Beschriftungen
> für ihre Buttons. Aus diesem Grund legt sie Objekte einer zweiten Klasse
> an ("Klasse B"), deren Attribut xy die Beschriftung ergibt.
>
> Betätige ich z.B. einen dieser Buttons, öffnet sich eine zweite View
> ("Klasse C"), aus der heraus ich die Objekte von "Klasse B" verändern
> können möchte (AUCH Atrribut xy, welches idealerweise beim zurückkehren
> zur ersten View aktualisiert ist).

Kannst du die Dinger nicht beim Namen nennen. Dir da jetzt eine STruktur 
auf Spekulationsbasis vorzuschlagen ist ... Kaffeesatzleserei.
Lesbare Bezeichnungen, die implizit ein wenig Information über deine 
Applikation verraten, wären von Vorteil.

> Betätige ich z.B. einen dieser Buttons,

Wer behandlet die Buttonbetätigung?
Ich nehme mal an, das wird A sein.

C klingt für mich nach einem Editor oder Einstelldialog um B Objekte 
(oder nur 1 B-Objekt?) zu verändern.

Wer oder was hindert daher A, wenn es das C-Fenster erzeugt und den 
Auftrag zum Editieren gibt, ihm seine Sammlung von B-Objekten (oder nur 
dieses 1 B-Objekt) mitzugeben?

Wenn sowohl A als auch C gleichzeitig offen sein sollen und mehr oder 
weniger unabhängig voneinander funktionieren sollen, dann kann man 
natürlich auch die Sammlung von B-Objekte von A wegnehmen und in eine 
übergeordnete Klasse (vielleicht eine Klasse welche die Applikation 
repräsentiert, oder eben eine Dokumentklasse) verlagern.

2 Fragestellungen muss man sich daher stellen
* Sind die B-Objekte nicht überhaupt an der falschen Stelle, wenn sie
  in A gespeichert sind?
  Nur weil A sie benutzt, muss das ja nicht heißen, dass sie logisch
  gesehen zu A gehören
* Ist C ein Dialog (den man mit OK bestätigen muss) oder ein Fenster
  welches unabhängig von allen anderen offen sein kann (zb eines
  der lange Zeit beliebten Property-Fenster, die an ein Hauptfenster
  angedockt sind)

von Klaus W. (mfgkw)


Lesenswert?

derjenigewelcher schrieb:
> ...
> Betätige ich z.B. einen dieser Buttons, öffnet sich eine zweite View
> ("Klasse C"), aus der heraus ich die Objekte von "Klasse B" verändern
> können möchte (AUCH Atrribut xy, welches idealerweise beim zurückkehren
> zur ersten View aktualisiert ist).

Ein A erzeugt ein C?
Dann gib doch einfach im Konstruktor von C mit, was C braucht
(also das B).
A erzeugt also nicht mit meinC=new C(), sondern meinC=new C(meinB).


> ...

(Nachtrag: sorry, hat KHB ja auch schon vorgeschlagen.
Ich finde es trotzdem gut :-)

von derjenigewelcher (Gast)


Lesenswert?

> Kannst du die Dinger nicht beim Namen nennen. Dir da jetzt eine STruktur
> auf Spekulationsbasis vorzuschlagen ist ... Kaffeesatzleserei.

Würde ich gerne, aber ehrlich gesagt ist das Ganze noch nicht so weit 
gediegen... Aber es ist ja auch durchaus ein eher grundlegendes Problem:

> Wenn sowohl A als auch C gleichzeitig offen sein sollen und mehr oder
> weniger unabhängig voneinander funktionieren sollen, dann kann man
> natürlich auch die Sammlung von B-Objekte von A wegnehmen und in eine
> übergeordnete Klasse (vielleicht eine Klasse welche die Applikation
> repräsentiert, oder eben eine Dokumentklasse) verlagern.

klingt für mich - wie schon oben erwähnt - sehr sinnvoll. Nur: Erzeuge 
ich mir die Objekte in meiner View, kann ICH das zum Beispiel wunderbar 
beim Laden dieser View veranlassen. Anders kann ICH das leider nicht ;) 
Wie würde ich die "Sammlung" auslagern und vor allem wie nutzen (also 
Objektmethoden nutzen umd die Objekte zu modifizieren, etc.)? Welche 
Methoden muss die (Dokument-)Klasse hierzu bereitstellen?

> 2 Fragestellungen muss man sich daher stellen
> * Sind die B-Objekte nicht überhaupt an der falschen Stelle, wenn sie
>   in A gespeichert sind?
>   Nur weil A sie benutzt, muss das ja nicht heißen, dass sie logisch
>   gesehen zu A gehören

Wie gesagt: Ja, ich denke Sie sind an der falschen Stelle (Weil A ja 
nunmal der View zugehörig ist).

> * Ist C ein Dialog (den man mit OK bestätigen muss) oder ein Fenster
>   welches unabhängig von allen anderen offen sein kann (zb eines
>   der lange Zeit beliebten Property-Fenster, die an ein Hauptfenster
>   angedockt sind)

ein Dialog (den man mit OK bestätigen muss).

von derjenigewelcher (Gast)


Lesenswert?

> Ein A erzeugt ein C?
> Dann gib doch einfach im Konstruktor von C mit, was C braucht
> (also das B).
> A erzeugt also nicht mit meinC=new C(), sondern meinC=new C(meinB).

Ja, in der Richtung habe ich das so auch bereits umgesetzt. Komisch 
wirds halt, wenns wieder in die andere Richtugn geht (A also noch 
existiert und ich also keinen Konstruktoraufruf nutzen kann). Davon ab 
ist es - s. oben - vermutlich auch einfach die falsche Klassenstruktur 
und -zuständigkeit.

von Karl H. (kbuchegg)


Lesenswert?

derjenigewelcher schrieb:
>> Kannst du die Dinger nicht beim Namen nennen. Dir da jetzt eine STruktur
>> auf Spekulationsbasis vorzuschlagen ist ... Kaffeesatzleserei.
>
> Würde ich gerne, aber ehrlich gesagt ist das Ganze noch nicht so weit
> gediegen... Aber es ist ja auch durchaus ein eher grundlegendes Problem:

Die Sache ist die, dass es für so ein grundlegendes Problem mehrere 
Ansätze geben kann, je nachdem welche konkrete Ausprägung des 
grundlegenden Problems vorliegt.
"One size fits all" funktioniert in der SW-Entwicklung seher selten.


> klingt für mich - wie schon oben erwähnt - sehr sinnvoll. Nur: Erzeuge
> ich mir die Objekte in meiner View, kann ICH das zum Beispiel wunderbar
> beim Laden dieser View veranlassen. Anders kann ICH das leider nicht ;)

Ist ja kein Problem.
Die View gehört ja auch irgendwo dazu. Die existiert ja auch nicht im 
luftleeren Raum. Im simpelsten Fall ist diese View ja Teil der 
Applikation. Und klar kann die View dann bei ihrem Vaterobjekt (=die 
Appliaktion oder das Document/Model) veranlassen, dass diese das B 
Objekt erzeugt und speichert (und meinetwegen einen Pointer darauf als 
Returnwert an das Viewobjekt wieder zurückgibt)

(Ein Document/Model kennt alle seine Views. Ein View kennt sein 
Document/Model zu dem er gehört)

Allerdings erhebt sich hier schon wieder die nächste Frage: Warum lädt 
eigentlich eine View Daten? Eine View ist dafür zuständig Daten 
anzuzeigen. Datenmanipulation (und da gehört auch Laden/Speichern dazu) 
sind Aufgabe des Documents/Model.


>> * Ist C ein Dialog (den man mit OK bestätigen muss) oder ein Fenster
>>   welches unabhängig von allen anderen offen sein kann (zb eines
>>   der lange Zeit beliebten Property-Fenster, die an ein Hauptfenster
>>   angedockt sind)
>
> ein Dialog (den man mit OK bestätigen muss).

Dann kann es durchaus sein, dass du damit durch kommst. Aber bei mir 
verdichtet sich der Verdacht, dass der Klassenaufbau nicht stimmt bzw. 
die Zuständigkeiten nicht klar geregelt sind

von derjenigewelcher (Gast)


Lesenswert?

> Allerdings erhebt sich hier schon wieder die nächste Frage: Warum lädt
> eigentlich eine View Daten?

Hmm... leider sehr banale Antwort: Weil ich es nicht besser wusste. Bzw. 
besser wusste schon, nur nicht besser umsetzen konnte ;)

Die View war die erste, die auf die Objekte zugreifen musste - eben um 
an die Beschriftungen zu kommen. Und so nahm es seinen Lauf...

> Im simpelsten Fall ist diese View ja Teil der
> Applikation. Und klar kann die View dann bei ihrem Vaterobjekt (=die
> Appliaktion oder das Document/Model) veranlassen, dass diese das B
> Objekt erzeugt und speichert

Was sind denn hier die richtigen Stichpunkte, nach denen ich mich vllt 
mal umhören müsste? Der Begriff "Delegate" ist mir wiederholt 
untergekommen, ich kann nur noch nicht recht einordnen, ob das in die 
richtige Richtung geht.. Es würde ja bedeuten: Ich weise aus A eine 
(übergeordnete Klasse an) mir Objekte zu erzeugen, die dann andere 
Klassen gleichermaßen nutzen können?

von Karl H. (kbuchegg)


Lesenswert?

derjenigewelcher schrieb:

> Was sind denn hier die richtigen Stichpunkte, nach denen ich mich vllt
> mal umhören müsste? Der Begriff "Delegate" ist mir wiederholt
> untergekommen,

Delegates gibt es (leider) in C++ nicht.

> ich kann nur noch nicht recht einordnen, ob das in die
> richtige Richtung geht.. Es würde ja bedeuten: Ich weise aus A eine
> (übergeordnete Klasse an) mir Objekte zu erzeugen, die dann andere
> Klassen gleichermaßen nutzen können?

Ja. Normaler Klassenaufbau

An der Spitze steht das Applikationsobjekt.
Machst du dort im Menü zb ein Datei öffnen, dann wird dafür ein Document 
erzeugt. Dieses Document ist dafür zuständig sich um alle Belange zu 
kümmern die mit Datenhaltung/Datenmanipulation zu tun haben. Wenn deine 
Applikation mit Geschäftsumsätzen zu tun hat, dann ist genau diese 
Klasse der richtige Punkt, um dort Arrays, Listen, (was auch immer) mit 
den Zahlenwerten zu haben.
Jedes Document kann mehrere Views besitzen. Ein View weiß selbst nicht 
viel über die Daten oder wie sie manipuliert werden. Aber er weiß, wie 
er sie anzeigen muss. Da gibt es dann zb. einen View, der die Umsätze in 
Tabellenform anzeigt. Ein anderer macht daraus vielleicht ein Diagramm, 
etc.

Mit so einem Aufbau (MDI) kann dann das Programm gleichzeitig und 
unabhängig voneinander mehrere Dateien offen haben und gleichzeitig für 
jede Datei mehrere Views anzeigen. Und wenn man über einen View einen 
Wert ändert, aktualisieren sich alle anderen Views, die auch zu diesem 
Dokument gehören. Grundvoraussetzung dabei ist: Nicht der View macht die 
Manipulation der Daten (weil zb der auslösende Button Teil des Views 
ist), sondern der View informiert sein Dokument, dass er (= das 
Document) Daten ändern soll. Das Document führt die Änderung aus und 
benachrichtigt wiedrrum alle seine Views, dass sich die Daten geändert 
haben.

Mann kann über Microsoft schimpfen soviel man will. Aber zumindest den 
Teil haben sie in der MFC richtig gemacht.

Ob deine Applikation jetzt tatsächlich mehrere Documente halten könenn 
muss oder nicht ... ob es für ein Document tatsächlich mehrere Views 
geben kann oder nicht ... muss man im Einzelfall entscheiden. Aber das 
Um und Auf ist die strikte Trennung zwischen Datenhaltung/Manipulation 
und DatenAnzeige. Die würde ich um nichts in der Welt aufgeben und mir 
verwässern, nur weil es auf den ersten Blick einfacher erscheint, 
Datenänderungen in einem View zu machen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.