Auf Objekte des Elternobjekts zugreifen...?



  • Hallo Leute,

    ich habe folgendes Problem.

    Eine Anwendung erzeugt ein Objekt der Klasse Workspace. Dieses Objekt existiert immer. Des Weiteren erzeugt es über einen Menüpunkt ein Objekt eines Dialogfensters:

    fmbMonitor::fmbMonitor()
    {
        setWindowTitle("fmbMonitor");
        // noch ein paar Objekte erzeugen
    
        // ein Workspace-Objekt erstellen
        Workspace *workspace = new Workspace(this);
        workspace->show();
    
        // ein Konfigurationsdialog erstellen
        AddViewDialog *addViewDialog = new AddViewDialog(this);
        addViewDialog->show();
    
        //Fertig, funktioniert auch alles
    }
    

    Was muss ich nun machen, damit ich aus dem Objekt vom Typ AddViewDialog auf Methoden und Membervariablen des Objekts vom Typ Workspace zugreifen kann??
    Ich dachte ja, dass die erzeugten Objekte sich jeweils gegenseitig 'kennen'.

    Hat jemand eine Idee?

    Grüße

    Christian



  • Nein, die Objekte "kennen" sich nicht gegenseitig, die mußt du schon einander "vorstellen" (indem du Zeiger herumreichst) - und nach Ende der Funktion kennst nicht mal du das erzeugte Workspace-Objekt (Speicherleck ⚠ ).

    PS: Wenn du im gesamten Programm nur EIN Workspace-Objekt hast, solltest du mal nach "Singleton" suchen. (wenn jeder fmbMonitor seinen eigenen Workspace hat, solltest du diesen als Klassenmember anlegen)



  • dem Dialog einen Pointer auf den Workspace im Konstruktor mitgeben
    oder die Methoden im Workspace als static deklarieren



  • ui, das gin ja schnell;

    Ok, das mit den Zeigern werde ich so machen. Kein Problem.

    Das Speicherleck sehe ich da im moment aber nicht... ich erzeuge ja im AddViewDialog kein neues Objekt, sondern will dort nur Objekte im Objekt Workspace (sogenannte Views) hinzufügen.
    Dazu rufe ich eine Methode des Objekts Workspace auf, dass sie selber (also dem Workspace) ein View hinzufügt. Die dazu nötigen Parameter werden im AddViewDialog eingestellt.

    So habe ich mir das zumindest vorgestellt 😉

    Danke!



  • Nein, im AddViewDialog sehe ich auch keine Speicherlecks (liegt wohl daran, daß ich von der Klasse gar nichts sehe), aber in der angegebenen Funktion selber. Die Zeiger 'workspace' und 'addViewDialog' sind lokal in deiner Funktion und gehen mit Funktionsende verloren - der Speicher, den du mit new angefordert hast, wird aber bis dahin nicht wieder freigegeben, also verlierst du jeden vorhandenen Bezug zu den erzeugten Objekten. Und das hat zur Folge, daß du nach dem Ende der Funktion weder etwas mit den beiden Objekten machen noch sie wieder zerstören kannst - ein Speicherleck ist geboren.

    (C++ hat keinen Garbage Collector - und "normale" Zeiger sind auch nicht intelligent genug, hinter sich aufzuräumen (wäre auch katastrophal, wenn jeder Zeiger seine Daten delete'n würde, wenn er aus dem Scope fliegt))



  • Achso, das meinst du.

    da mache ich mir keine Sorgen. Ich arbeite mit QT. QT hat einen Garbage Collector der immer dann aktiviert wird, wenn ein Parent-Objekt zerstört wird.

    grüße

    Christian



  • Na gut, dann will ich zu dem Speicherleck nichts gesagt haben - trotzdem weiß (außer eventuell dem GC) nach dem Ctor niemand mehr, wo dein Workspace-Objekt sich versteckt hat.

    (die Lösung hatte ich vorhin schon genannt - leg dein Workspace-Objekt als Klassenmember an)



  • habe ich noch nicht verraten:

    das Workspace-Objekt ist ein Klassen-Member, hatte es nur vorhin als lokales Objekt erzeugt, um den zu tippenden Code hier klein zu halten 😉
    Copy & Paste von einen PC auf den anderen geht nämlich noch nicht so gut 😉

    Grüße!



  • bw1faeh0 schrieb:

    Achso, das meinst du.

    da mache ich mir keine Sorgen. Ich arbeite mit QT. QT hat einen Garbage Collector der immer dann aktiviert wird, wenn ein Parent-Objekt zerstört wird.

    grüße

    Christian

    das gilt aber nur bei Qt-Objekten



  • CStoll schrieb:

    Na gut, dann will ich zu dem Speicherleck nichts gesagt haben - trotzdem weiß (außer eventuell dem GC) nach dem Ctor niemand mehr, wo dein Workspace-Objekt sich versteckt hat.

    Sowas ist in Qt garnicht so ungewöhnlich. Man legt (z.B.) einen Button an, dem man im Konstruktor this übergibt. Der Konstruktor der Oberklasse QObject baut dabei eine Baumstruktur auf, und der Destruktor von QObject räumt automatisch alle registrierten Kinder ab. Signale dieses Buttons verbindet man evtl. noch mit einem Slot, danach lässt man den Pointer fallen. Das Objekt "weiss" ja, wen es anfunken muss wenn ein Ereignis eintritt, und das Elternobjekt "weiss", wann es das Kind löschen muss.



  • LordJaxom schrieb:

    Sowas ist in Qt garnicht so ungewöhnlich. Man legt (z.B.) einen Button an, dem man im Konstruktor this übergibt. Der Konstruktor der Oberklasse QObject baut dabei eine Baumstruktur auf, und der Destruktor von QObject räumt automatisch alle registrierten Kinder ab. Signale dieses Buttons verbindet man evtl. noch mit einem Slot, danach lässt man den Pointer fallen. Das Objekt "weiss" ja, wen es anfunken muss wenn ein Ereignis eintritt, und das Elternobjekt "weiss", wann es das Kind löschen muss.

    Nur aus Neugierde - kann ich diese Baumstruktur eigentlich auch ausnutzen, um meine Kinder wiederzufinden? (z.B. weil ich diesen Button zwischenzeitlich deaktivieren oder neu beschriften will)



  • CStoll schrieb:

    Nur aus Neugierde - kann ich diese Baumstruktur eigentlich auch ausnutzen, um meine Kinder wiederzufinden? (z.B. weil ich diesen Button zwischenzeitlich deaktivieren oder neu beschriften will)

    Kann man, wenn man dem Ctor zusätzlich zum Parent-Pointer (this) noch einen Namen in Form eines char const* mitgibt. Wenn ich das allerdings wirklich bräuchte, wäre ich (salopp gesagt) allerdings bescheuert, dafür eine rekursive Suche zur Laufzeit zu bemühen 😃



  • Noch bescheuerter wäre es ohnehin, mit dynamischen GUI-Masken zu arbeiten 😃 (ausser ich mag den User quälen)

    also entweder ich habe Elemente, die ich aktivieren oder deaktivieren will. dann hab ich eh fixe pointer auf die buttons

    oder ich denk mir gleich ne vernünftige GUI aus, zB als Tabelle für variierende Elemente etc



  • crashterpiece schrieb:

    Noch bescheuerter wäre es ohnehin, mit dynamischen GUI-Masken zu arbeiten 😃 (ausser ich mag den User quälen)

    Das hängt von den Umständen ab - manchmal ist es durchaus nützlich, erst zur Laufzeit Buttons u.ä. zu ergänzen (und es ist auch wesentlich ressourcensparender, nur die 10 Buttons anzulegen, die ich gerade benötige, als auf Vorrat 200 Buttons zu erzeugen, von denen maximal 10 sichtbar sind).

    (btw, ich arbeite eher mit MFC - aber dort sind die grundlegenden Mechanismen recht ähnlich (nur daß die nicht mit Zeigern arbeitet, sondern mit Fenster-Handles - und viele Aufgaben der WinAPI überlässt))


Log in to reply