Wie Sie bereits betont haben, muss das Kind selbst selten, wenn überhaupt, auf das Elternteil zugreifen müssen, solange das Elternteil die gesamte Arbeit erledigt und den Überblick über seine Kinder behält. Der Klassiker getParent
ist jedoch am nützlichsten, wenn Sie das Framework von außen verwenden.
Szenario
Eine einfache Operation, die Probleme verursachen kann, ist die folgende: Wie funktioniert das Austauschen, wenn zwei konkrete Widgets irgendwo in Ihrem gesamten Widget-Baum vorhanden sind und ein Anwendungsfall vorliegt, bei dem Sie diese beiden austauschen müssen?
Option 1: Sagen Sie es den Kindern
Sagen Sie es Ihrem Kinder-Widget swap(withOtherChild)
. Beim Austauschen wird jedoch die Datenstruktur der untergeordneten Kinder auf irgendeine Weise aktualisiert. Wie erreichen Sie dies, da Ihr Kind seine Eltern nicht kennt?
Option 2: Sagen Sie es den Eltern
Bitten Sie die Eltern eines Kindes, es zu entfernen und das andere hinzuzufügen. Oh warte, das gleiche Problem. Sie haben nur die untergeordneten Objekte und es gibt keine getParent
auf diesen.
Option 3: Grunzarbeit
Als letzte Option können Sie Ihren gesamten Widget-Baum durchlaufen, um ein übergeordnetes Element mit hasChild(x)
und eines mit zu finden, hasChild(y)
und dann auf Option 2 zurückgreifen.
Lösung
Sie sollten das übergeordnete Element behalten, wenn Sie jemals große Widget-Bäume erstellen und Vorgänge ausführen möchten, bei denen die Position eines Widgets im Baum verschoben werden muss. Wenn Ihre Widget-Bäume sehr klein sind oder nur eine sehr geringe Tiefe, aber schnelle hasChild
Zugriffsmethoden haben, ist Option 3 möglicherweise für Sie akzeptabel und Sie können die übergeordnete Referenz weglassen.
Referenzen in Datenstrukturen im Allgemeinen
Sie planen hier, eine Datenstruktur für einen Baum aufzubauen. Betrachten wir eine Vereinfachung und nehmen wir aus Gründen der Argumentation an, dass jedes Widget nur ein Kind haben kann. Das Ergebnis ist natürlich eine Liste, und Ihre Frage lautet nun "Soll ich eine einfach oder doppelt verknüpfte Liste haben?".
Und genau wie bei Listen gibt es keine eindeutige Antwort, sondern nur Vor- und Nachteile. Offensichtliche Vorteile für Single-Linked (dh keine übergeordnete Referenz) sind a) einfacher zu implementieren und b) weniger Speicher. Zu den Nachteilen gehören jedoch a) einige Operationen werden langsam, da sie die Struktur durchlaufen müssen, und b) ein nicht einfacher Zugriff auf diese Operationen kann bedeuten, dass die Verwendung der Datenstruktur umständlich ist, und c) sie verwendet mehr Speicher.
Andererseits kehrt die doppelt verknüpfte Variante, dh mit übergeordneter Referenz, diese Vor- und Nachteile ziemlich um.
In Bezug auf eine GUI-Bibliothek / ein GUI-Framework sind die Speicherbeschränkungen normalerweise kein Problem, das übergeordnete Zeiger verbietet. Wenn Sie dies ausschließen und feststellen, dass es sich um eine Bibliothek / ein Framework handelt und es daher vorzuziehen ist, dass es schwer zu implementieren, aber einfach zu verwenden ist, schließen Sie die oben genannten Vorteile eines Single-Linked-Ansatzes im Wesentlichen aus.
Ich bin mir der Besonderheiten Ihres Projekts nicht bewusst, daher möchte ich Sie nicht auffordern, die übergeordnete Referenz beizubehalten, da einige meiner obigen Überlegungen in Ihrem Fall möglicherweise nicht zutreffen. Im Allgemeinen halte ich übergeordnete Referenzen in einer Widget-Datenstruktur aus den oben genannten Gründen jedoch für sinnvoll.
Ich würde sagen, wenn die Kinder ihre Eltern kennen, bilden ein Widget und alle seine Vorfahren eine Verantwortungskette . Ein typisches Beispiel ist ein Mausereignis, das von einem Widget empfangen wird: Das Widget kann entweder das Ereignis konsumieren (und entsprechend reagieren) oder das Ereignis an sein übergeordnetes Ereignis übergeben, das es entweder konsumieren oder an sein übergeordnetes Element übergeben kann, usw.
Im Fall von Qt erhält jedes Widget vom Konstruktor sein übergeordnetes Element. Dies zeigt an, dass das Widget dem übergeordneten Element gehört. Insbesondere das Löschen des übergeordneten Elements löst das Löschen des Widgets aus.
quelle