Gültigkeit von Zeigern auf Instanzen
-
Irgendwie stehe ich heute auf dem Schlauch:
[cpp]Header-Datei
class GUIBase
{
public:
GUIBase(IIDECL1500::sICFCmd& cmd, CMDInterpreter* pInterpreter);
virtual ~GUIBase();
...
virtual void Create();
...
protected:
...
IIWidget* m_pWidget;
IIWidget* m_pparentWidget;
...
}class GUILabel : public GUIBase
{
public:
GUILabel(IIDECL1500::sICFCmd& cmd, CMDInterpreter* pInterpreter);
virtual ~GUILabel();
virtual void Create();
}
[/cpp]Destruktoren GUIBase::~GUIBase() { //m_pWidget ist möglicherweise schon gelöscht try { delete m_pWidget; } catch ( ... ) { } ... } GUILabel::~GUILabel() { }
Innerhalb von Create werden die entsprechenden Instanzen erzeugt und auf IIWidget heruntergecastet (was für ein Wort) und in m_pWidget abgelegt.
Da IIWidget über eine eigene Speicherverwaltung verfügt und z. B. alle Kindelemente selbständig löscht und ich andererseits (derzeit) nicht kontrollieren kann, in welcher Reihenfolge die Destruktoren aufgerufen werden, zeigt m_pWidget in vielen Fällen auf eine Instanz, die nicht mehr existiert, da eine vorhergehende Zerstörung auch alle IIWidget-Kind-Instanzen zerstört hat.
Nun kann ich das Problem sicherlich dadurch umgehen, das
1. GUIBase selbst seine abhängigen Kinder verwaltet
2. Ich sicherstelle, dass immer erst die Kinder und dann die Eltern gemeuchelt werden.Das bedeutet jedoch ziemlich viel Programmieraufwand.
Der obige Versuch, durch try und catch die Exceptions abzufangen ist einmal nicht gerade performant und führt irgendwann (nicht beim ersten Mal!!) zu einer ESP-Fehlermeldung:
The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a diffent calling convention.
Die Fragen:
1. Gibt es noch eine andere Möglichkeit, die Gültigkeit des Pointers zu prüfen?
2. Was soll diese Fehlermeldung?
-
zu 1:
nö soweit ich weiß nedzu 2:
prinzipiell heisst das, dass die funktion z.b. __stdcall benutzt und du sie mit __cdecl aufrufstin deinem fall würd ich tippen, dass er den nirvana zeiger benutzt und der speicher an der stelle ihm zufällig so scheint als wärs n gültiges objekt
er nimmt also den wert an der speicherstelle an der er die besagte funktion erwartet, ruft die adresse als funktion auf und merkt dass der aufruf irgendwie ned klapptüberarbeite lieber mal dein konzept oder benutz reference counting damit objekte erst gelöscht werden, wenn niemand mehr n zeiger auf sie besitzt
-
mal sehen ob ich verstanden habe
wenn guibase alle kinder verwaltet wieso schreibst du dann nicht guibase als so ne art factory um?GuiBase *Create() // erstellen der instanz und verwalten, sprich auch löschen
-
Danke für die schnellen Antworten, auch wenn ich mir etwas einfacheres vorgestellt habe.
Sovok schrieb:
...benutz reference counting damit objekte erst gelöscht werden, wenn niemand mehr n zeiger auf sie besitzt
Danke, dann verstehe ich vielleicht auch mal, was das hier soll
:
static unsigned long refCount () { return myRefCounter ; } static unsigned long instCount () { return myInstCounter ; }
Muss ich mir bei Gelegenheit mal näher anschauen.
Ich werde GUIBase erstmal so erweitern, dass es seine Kinder mitverwaltet.
-
Hmm, du koenntest ja auch einfach immer nach dem loeschen auch den Pointer NULL setzten. Waere noch ein bisschen schoener und du kannst halt vorm loeschen generell pruefen ob der Pointer NULL ist. Dann muesstest du auch nich grossartig umschreiben..
Abgesehen davon ist es sehr untypisch das Oberklassen ihre Kinder verwalten.
-
PunI$0R schrieb:
Hmm, du koenntest ja auch einfach immer nach dem loeschen auch den Pointer NULL setzten. Waere noch ein bisschen schoener und du kannst halt vorm loeschen generell pruefen ob der Pointer NULL ist. Dann muesstest du auch nich grossartig umschreiben..
Abgesehen davon ist es sehr untypisch das Oberklassen ihre Kinder verwalten.
1. ne geht nich weil mehrere pointer auf dasselbe objekt existieren, welche sich in verschiedenen instanzen befinden und somit nichts voneinander wissen/keinen zugriff aufeinander haben
2. es is nicht untypisch, dass oberklassen ihre kinder verwalten siehe QT http://www.trolltech.com/
-
Tja mag wohl sein das irgendwer das macht, das Oberklassen ihre Kinder verwalten. Nur die Frage ist einfach, wie sinnvoll das ist. Wenn man spaeter ne neue Klasse oder mehrere dazu schreibt, muss auch die Oberklasse wieder angepasst werden.
Ist das denn wirklich objektorientiert??
-
Nachdem ich zunächst mein Problem von meinen Klassen nach QT verschoben hatte (jetzt hatte QT nix mehr zum Löschen
) habe ich die mörderische Arbeit jetzt aufgeteilt und es funktioniert.
Trotzdem wäre es schön gewesen, da ich mich irgendwie an eine entsprechende Systematik in Delphi erinnern konnte (beschränkt sich aber auf eine globale Festlegung, das bei jedem Dispose der Zeiger auf nil (=NULL) gesetzt wird).
Aber wer sagt denn, das C++ eine ausgereifte Sprache ist?
Sovok schrieb:
Ist das denn wirklich objektorientiert??
Wie sollen den 1:n-Abhängigkeiten von Klassen sonst verwaltet werden? Dies trifft für jede Art von Masken, Listen und Dictionaries zu.
-
Manfred Schmidtke schrieb:
Sovok schrieb:
Ist das denn wirklich objektorientiert??
bitte richtig zitieren