2010-07-14 7 views
5

Ich habe ein Problem mit ein paar Event-Handler-Klassen zu schreiben, ich versuche. Grundsätzlich besteht die Idee darin, für jede logische Gruppe von Objekten eine Event-Handler-Klasse zu haben. In den meisten Fällen liegen die Ereignisse zwischen Objekten und ihrem Handler, aber in einigen Fällen werden auch Ereignisse zwischen Handler-Objekten gesendet.Aufruf auf das gleiche Objekt auf zwei Zeiger löschen

ich den Code geschrieben haben, so dass die Ereignisse auf einen Stapel gelegt werden (Stapel wie in Benutzer erstellt Struktur, die Ereignisse selbst zugeordnet sind mit new) und delete d nach deren Informationen gelesen und befolgt werden. Das gibt mir einige Probleme, weil in einem Fall das Ereignis entlang einer Kette von drei Handlern gesendet wird. Sprich, sendet HandlerA eine new Event zu HandlerB, die es auf dem Stapel platziert und liest sie, es zu HandlerC senden, die er liest und was auch immer es ausführen muss, nach dem es delete s der Ereigniszeiger und setzt es auf NULL. Nun machen wir einen Abstecher zu HandlerB zurück und, na ja, es will auch delete und NULL der Zeiger auf das Ereignis. Aber der Zeiger ist eine lokale Variable, und es endet am Löschen der gleichen Adresse zweimal, was eine Ausnahme gibt.

Wie gehen Sie diese um? Sie benötigen einen dieser Phantasie auto_ptr s benutzen (noch ein hier früh Lerner), oder bin ich etwas fehlt hier grundlegend?

+0

Die Ereignisse werden auf Stapel zugeordnet oder sie werden auf Heap (mit neuen) zugewiesen und in einer Stack-Datenstruktur gespeichert? – Naveen

+0

Die Ereignisse werden auf dem Heap unter Verwendung von new zugewiesen und in einer Stapelstruktur gespeichert. Ich denke, ich sollte den Wortlaut oben ändern ... –

Antwort

10

ich den Code so geschrieben habe, dass die Ereignisse auf einen Stapel gelegt werden und gelöscht werden, nachdem ihre Informationen gelesen und befolgt werden.

Es gibt einige Verwirrung hier - Objekte auf dem Stapel sollte nicht delete d sein. Objekte, die mit new (auf dem Heap) erstellt wurden, sollten.

Im Allgemeinen sollten Sie eine klare Eigentümerstrategie für Ihre Objekte auf dem Heap definieren. Jedes Objekt sollte einen Eigentümer haben, und es sollte klar sein, wer der Besitzer zu irgendeinem Zeitpunkt ist. Dieser Besitzer - und es allein - soll das Objekt delete sein.

Sie können auch boost::shared_ptr (es kann auch als std::tr1::shared_ptr, abhängig von Ihrem Compiler verfügbar sein) anstelle von rohen Zeigern verwenden. Damit werden die Referenzen auf das Objekt gezählt, und delete wird angezeigt, wenn der Ref-Zähler auf 0 fällt.

+0

Ich meinte auf einer vom Benutzer erstellten Stack-Struktur, nicht in dem Sinne, den Sie meinten. Es tut uns leid! –

+0

Ich denke, das OP bedeutet eine Stack-Datenstruktur und nicht den Stack. – Jackson

+0

@Kristian, ich sehe, danke für Ihre Klarstellung. Dann ist das Problem nicht so schlimm wie es zuerst schien :-) –

6

Sie möchten einen Zeiger-Wrapper, der für Instanzen die Referenzzählung verwendet, um zu überprüfen, ob andere Variablen auf dieselbe Instanz verweisen. Die Idee ist, dass das Objekt, auf das der Zeiger zeigt, nur freigegeben wird, wenn dieses Objekt von keinem anderen Zeiger verwendet wird. Diese Art von Zeigern wird allgemein als Smart Pointers bezeichnet. In C++ können Sie beispielsweise die von Boost bereitgestellten verwenden.

1

Das Problem, wie ich es sehe, ist, dass es keine klaren Besitzer des Zeigers ist. Eine Lösung werden intelligente Zeiger sein, wie in Inflagrantis Antwort darauf hingewiesen wird. Alternativ können Sie die Weiterleitung des Ereignisses zweimal abbrechen. Wenn ein Handler (Handler B in Ihrem Beispiel) ein Ereignis empfängt, das an einen anderen Handler weitergeleitet werden muss, erstellt er ein neues Ereignis und gibt den Zeiger nicht an das vorhandene Ereignis weiter.

Das sagte; Wenn Sie die Zeit damit verbringen wollen, in sie zu schauen, denke ich, dass die Smart Pointer-Lösung wahrscheinlich besser ist!