GUI System Nachbilden
-
Hey Leute.
Ich habe eine frage zu dem gui systemen.Ihr wist ja alle das man z.b bei wxWidgets und vllt. auch bei Qt alle Elemente mit einem new erzeugen muss, aber dazu kein delete schreiben muss?
Ich habe gehört das sie irgentwas eingebaut haben ,aber ich weiß nicht mehr was.1.) Was ist das für ein System?
2.) Wie funktioniert das?
3.) Wie ist der aufgebaut?
4.) Wie kann man so etwas selber machen?
5.) Gibt es irgentwelche tut's dafür?Danke im Voraus!
Mfg Wikinger75!
-
Wie sie das machen, weiss ich nicht, aber grundsätzlich ist das ganz einfach.
class manager : public singleton { public: register ( item* i ){...} }; class item { public: item () { manager::inst ()->register ( this ); } };Du registrierst einfach jedes Objekt in dem gewünschtem Manager. Der Manager regelt dann die Objekte und deren zerstörung. Dazu muss man sich aber noch ein paar Gedanken machen, was passieren soll, wenn ein Objekt kopiert wir (reference counting z.B) oder jemand das Objekt trotzdem mit delete zerstört.
-
Also ich weis nicht wie sies genau gemacht haben, du kannst aber zum Beispiel dafür sorgen das sich dein erzeugtes Element bei einer Verwaltungsklasse anmeldet die sich um die ganzen deletes kümmert wenn das Programm beendet wird.
-
Das System ist eigentlich ganz einfach und betrifft nur die Fenster (also auch Controls). Da alle Fenster in einer Baumstruktur aufgebaut sind, hat jedes Fenster ein übergeordnetes Fenster. Das übergeordnete Fenster löscht einfach per
deletealle untergeordneten Fenster.
Es wird einfach in jedem übergeordnetem Fenster eine Liste mit Zeigern von untergeordneten Fenstern mitgeführt. Jedes neu erstelle Fenster muss sich daher entsprechend beim übergeordneten Fenster anmelden.Die Fenster werden dann über die Methode
Destroy()gelöscht. Laut wxWidgets braucht es dieseDestroy()Methode, da es sonst zu Fehlern kommen kann:
http://wiki.wxwidgets.org/Avoiding_Memory_Leaks#The_wxWidgets-specific_partTatsächlich hätte aber ein sauberes Design dies unnötig gemacht und man hätte auch bessere RAII Möglichkeiten mit wxWidgets. Aber die Bibliothek ist halt uralt und setzt auf veraltete Konzepte.
Ich rate dir aufzupassen, wenn du in solche Richtungen gehst. Lass dem User lieber die Möglichkeit, dass er selber entscheiden kann. Für sichere Heapspeicherverwaltung gibt es die Smartpointer:
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/smart_ptr.htmGrüssli
-
Wie sie das machen, weiss ich nicht, aber grundsätzlich ist das ganz einfach.
class manager : public singleton { public: register ( item* i ){...} }; class item { public: item () { manager::inst ()->register ( this ); } };Du registrierst einfach jedes Objekt in dem gewünschtem Manager. Der Manager regelt dann die Objekte und deren zerstörung. Dazu muss man sich aber noch ein paar Gedanken machen, was passieren soll, wenn ein Objekt kopiert wir (reference counting z.B) oder jemand das Objekt trotzdem mit delete zerstört.
Hmm ja das Prinzip scheint schonmal eindeutig zu sein, doch leider versteh ich das nicht gant.
1.) register ( item* i ){...} <-- Raff ich nicht^^ z.b warum steht item* in klamern und warum ist da kein bezeichne dabei?
2.) manager::inst ()->register ( this );
Seit wan hat manager eine inst methode?
Warum steht hinter den klamern register? Is das net falsch?^^3.) Wie sieht überhaupt die Klasse singleton aus?
Also ich weis nicht wie sies genau gemacht haben, du kannst aber zum Beispiel dafür sorgen das sich dein erzeugtes Element bei einer Verwaltungsklasse anmeldet die sich um die ganzen deletes kümmert wenn das Programm beendet wird.
Ah gut^^
Das System ist eigentlich ganz einfach und betrifft nur die Fenster (also auch Controls). Da alle Fenster in einer Baumstruktur aufgebaut sind, hat jedes Fenster ein übergeordnetes Fenster. Das übergeordnete Fenster löscht einfach per delete alle untergeordneten Fenster.
Es wird einfach in jedem übergeordnetem Fenster eine Liste mit Zeigern von untergeordneten Fenstern mitgeführt. Jedes neu erstelle Fenster muss sich daher entsprechend beim übergeordneten Fenster anmelden.Die Fenster werden dann über die Methode Destroy() gelöscht. Laut wxWidgets braucht es diese Destroy() Methode, da es sonst zu Fehlern kommen kann:
http://wiki.wxwidgets.org/Avoiding_Memory_Leaks#The_wxWidgets-specific_partTatsächlich hätte aber ein sauberes Design dies unnötig gemacht und man hätte auch bessere RAII Möglichkeiten mit wxWidgets. Aber die Bibliothek ist halt uralt und setzt auf veraltete Konzepte.
Ich rate dir aufzupassen, wenn du in solche Richtungen gehst. Lass dem User lieber die Möglichkeit, dass er selber entscheiden kann. Für sichere Heapspeicherverwaltung gibt es die Smartpointer:
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/smart_ptr.htmGrüssli
Ok, dass erklärts nochmal ausführlich, danke^^
Tatsächlich hätte aber ein sauberes Design dies unnötig gemacht und man hätte auch bessere RAII Möglichkeiten mit wxWidgets. Aber die Bibliothek ist halt uralt und setzt auf veraltete Konzepte.
Ähm hier benötige ich erklärungen^^
Z.b wieso veraltet? Warum sollte man das nicht benutzen?
Ich finde das ganz logisch.Ich rate dir aufzupassen, wenn du in solche Richtungen gehst. Lass dem User lieber die Möglichkeit, dass er selber entscheiden kann. Für sichere Heapspeicherverwaltung gibt es die Smartpointer:
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/smart_ptr.htmDenn Tipp nehme ich gerne an^^
Jedoch weiß ich nit was das bringen sollte^^Naja aufjedenfall
1.) Danke für den Tipp^^
2.) Man ich hab kein Bock auf tausend externe Bibliotheken zurück zugreifen.
Da bastel ich mir das lieber selber sicher^^, möglich is das ja!Mfg Wikinger75!
-
Wikinger75 schrieb:
Z.b wieso veraltet?
wxWidgets ist uralt und wurde bis heute nicht sinnvoll renoviert. Es verwendet nicht mal die Möglichkeiten des C++ Standards von 1998. Es ist völlig in vergangenen Zeiten stecken geblieben und die Entwickler weigern sich mit allen Mitteln, einzusehen, dass sich die Welt und C++ weiterentwickelt haben.
Wikinger75 schrieb:
Warum sollte man das nicht benutzen?
Ich finde das ganz logisch.In C++ ist derjenige für den Speicher verantwortlich, der den Speicher anfordert.
Es ist eine unnötige Einschränkung, dass ich alle Objekte einzeln auf den Heap packen muss. Ich möchte vielleicht Objekte direkt in einer Klasse als Member ablegen. Das verbietet dieses System explizit und es gibt keinen Grund für diese Einschränkung.Klassen sollten in C++ so aufgebaut sein, dass es keine Rolle spielt, ob man nun ein Objekt auf dem Heap oder Stack ablegt. Es ist völlig unlogisch, dass es hier plötzlich eine Einschränkung gibt.
Wikinger75 schrieb:
Denn Tipp nehme ich gerne an^^
Jedoch weiß ich nit was das bringen sollte^^Bsp:
void foo_raw_ptr() { MyClass* ptr = new MyClass(); ptr->doSomething(); delete ptr; // Falls bei doSomething eine Exception fliegt, // wird der Speicher nicht freigegeben. } void foo_smart_ptr() { boost::scoped_ptr<MyClass> ptr(new MyClass()); ptr->doSomething; // delete nicht mehr nötig. Der SmartPtr erledigt es für uns. // Falls bei doSomething eine Exception fliegt, wird der Speicher auch freigegeben. }Das ist ein Beispiel für einen
boost::scoped_ptr. Einboost::shared_ptrbietet zum Beispiel die Möglichkeit an, dass der letzte, welcher einen Zeiger auf das entsprechende Objekt hält, den Speicher auch freigibt und das alles voll automatisch.Ein
scoped_ptrodershared_ptrkann man selber auch noch zusätzlich konfigurieren. Man kann ihnen auch Zeiger auf Stackobjekte geben, man muss dann nur die Anweisung geben, dass sie schlussendlich keindeleteaufrufen sollen. So kann eine Funktion einboost::shared_ptrerwarten und unter Umständen auch mit einem Zeiger auf ein Stackobjekt gefüttert werden. Auch ist es möglich einen Zeiger auf einen eigenen Speicherpool zu übergeben. Die Speicherverwaltung funktioniert auch hier, also eindeleteist überflüssig in jedem Fall und muss nicht mehr vom Programmierer aufgerufen werden.Wikinger75 schrieb:
2.) Man ich hab kein Bock auf tausend externe Bibliotheken zurück zugreifen.
Da bastel ich mir das lieber selber sicher^^, möglich is das ja!Hä?
(Sorry, aber da fällt mir wirklich nichts anderes mehr ein!)
Du erfindest also lieber jedesmal das Rad neu, statt auf bewährte, getestete und sichere Systeme zurückzugreifen?
Nichts dagegen, dass du es mal zum Lernen selber machen willst, aber für produktiven Code ist das nur absoluter Blödsinn.Grüssli
-
In C++ ist derjenige für den Speicher verantwortlich, der den Speicher anfordert.
Es ist eine unnötige Einschränkung, dass ich alle Objekte einzeln auf den Heap packen muss. Ich möchte vielleicht Objekte direkt in einer Klasse als Member ablegen. Das verbietet dieses System explizit und es gibt keinen Grund für diese Einschränkung.Klassen sollten in C++ so aufgebaut sein, dass es keine Rolle spielt, ob man nun ein Objekt auf dem Heap oder Stack ablegt. Es ist völlig unlogisch, dass es hier plötzlich eine Einschränkung gibt.
Hmm gut, also brauch ich das mit dem manager auch nicht mehr zu machen^^
Da seh ich auch ne logik drinne, aufjedenfall weiß ich jetzt auch warum der eine vorgang veraltet ist^^ Gut das mach ich mir mal zur Faustregel^^2.) Man ich hab kein Bock auf tausend externe Bibliotheken zurück zugreifen.
Da bastel ich mir das lieber selber sicher^^, möglich is das ja!Hä?
(Sorry, aber da fällt mir wirklich nichts anderes mehr ein!)
Du erfindest also lieber jedesmal das Rad neu, statt auf bewährte, getestete und sichere Systeme zurückzugreifen?
Nichts dagegen, dass du es mal zum Lernen selber machen willst, aber für produktiven Code ist das nur absoluter Blödsinn.Hmm nein, ich erfinde nicht jedes Rad neu, sondern nur manche^^
Und zwar erfinde ich ein Rad neu wenn ich nur eine Klasse brauche, aber sie nur bekomme wenn ich mir eine ganze gigantische lib runterladen muss
Mfg Wikinger75!
-
Dravere schrieb:
Du erfindest also lieber jedesmal das Rad neu, statt auf bewährte, getestete und sichere Systeme zurückzugreifen?
Für GUI in C++ wäre es vielleicht grundsätzlich gar nicht das Schlechteste, das Rad neu zu erfinden...

Nur sollte man dafür genügend Zeit, Wissen und Motivation haben. Auch gut wären genügend Leute.

-
Wikinger75 schrieb:
Hmm nein, ich erfinde nicht jedes Rad neu, sondern nur manche^^
Und zwar erfinde ich ein Rad neu wenn ich nur eine Klasse brauche, aber sie nur bekomme wenn ich mir eine ganze gigantische lib runterladen muss
Schau dir mal Boost an. Da kannst du noch extrem viel von verwenden. Ich verwende grundsätzlich in jedem Projekt in C++ Boost und zwar meistens mehrere Bibliotheken. Boost gilt zum Teil als inoffizielle Erweiterung zur Standardbibliothek von C++ und das nicht ohne Grund

Aber gut, Smart Pointer bekommst du auch im TR1:
std::tr1::shared_ptr. Das Teil ist in<memory>zu finden. Natürlich nur sofern du einen TR1 kompatibeln Kompiler hast
@Nexus,
Wo du recht hast, hast du recht
Grüssli
-
Auch wenn das schon vorbei ist:
1.) register ( item* i ){...} <-- Raff ich nicht^^ z.b warum steht item* in klamern und warum ist da kein bezeichne dabei?
2.) manager::inst ()->register ( this );
Seit wan hat manager eine inst methode?
Warum steht hinter den klamern register? Is das net falsch?^^3.) Wie sieht überhaupt die Klasse singleton aus?
1. Stell dir da einfach noch ein
voidvornedran vor.
2/3. Das ist eine gängige Implementierung eines Singletons. Man kann dann von einer Klasse ableite und hat eine Funktion zur Verfügung, die inst, oder so ähnlich heisst, wo man auf das Objekt zugreifen kann.GUI ist wirkliche Interessantes Thema, wo es viele Probleme zu lösen gibt. Die Ideale Lösung zu finden ist schwer, aber man kann sehr davon profitieren selbst mal etwas in dem Bereich gemacht zu haben. Ich bevorzuge auch etwas eigenes, obwohl es auch wirklich brauchbare Sachen gibt.

-
Übrigens ist
registerein denkbar schlechter Name für eine Methode.
-
Nexus schrieb:
Übrigens ist
registerein denkbar schlechter Name für eine Methode.
Jup, ist mir auch aufgefallen, aber der Name hat so schön gepasst..
