Das Zerstören von Glib :: RefPtr führt zu fehlgeschlagenen Zusicherungen im GTK 3-Kern
Die Jungs von Gtkmm sindvergleichen Glib::RefPtr
mitstd::auto_ptr<>
:
Glib::RefPtr
ist ein Smartpointer. Insbesondere handelt es sich um einen Smartpointer mit Referenzzählung. Sie kennen vielleichtstd::auto_ptr<>
, der auch ein smartpointer ist, aberGlib::RefPtr<>
ist viel einfacher und nützlicher.
Aber aus irgendeinem seltsamen Grund kann ich meine Arbeit mit dem nicht erledigenRefPtr
. Der gleiche Code ist gut mit einemauto_ptr
.
Im folgenden CodeSmartPtr
ist nur ein Platzhalter für einen dieser beiden Smartpointers.
<code>#include <gtkmm.h> #include <iostream> #include <tr1/memory> struct WindowHolder { SmartPtr<Gtk::Window> ptr; WindowHolder() : ptr(new Gtk::Window) { ptr->signal_delete_event().connect(sigc::mem_fun(*this, &WindowHolder::reset)); ptr->show_all(); } bool reset(GdkEventAny* event) { Gtk::Main::quit(); } }; int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); WindowHolder w; kit.run(); } </code>
Beim Kompilieren definiere ich zuerstSmartPtr
wieGlib::RefPtr
und dann alsstd::auto_ptr
.
<code>$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-3.0` main.cc && ./a.out (main:22093): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed $ g++ '-DSmartPtr=std::auto_ptr' `pkg-config --cflags --libs gtkmm-3.0` main.cc && ./a.out $ </code>
Das Problem ist das hierGLib-GObject-CRITICAL
. In meiner eigentlichen Anwendung ist dies nicht nur eine einzelne Zeile, sondern eine ganze Reihe von Zeilen. In der zweiten Version mitstd::auto_ptr
alles wird gut zerstört.
Seltsamerweise ist der Code in GTK 2 in Ordnung:
<code>$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out $ </code>
Ich möchte nicht davon abhängenstd::auto_ptr
weil es veraltet ist und ich auch nicht mit einem rohen Zeiger arbeiten möchte, weil dann die Destruktoren die Zeiger manuell löschen müssen, was zusätzliche Komplexität hinzufügt ...
Meine Fragen sind:
Warum verursachtGlib::RefPtr
diese "kritische Warnung" (wahrscheinlich ein doppeltes frei)?Warum funktioniert es mit gtkmm 2.4 aber nicht in 3.0?Kann ich den Code mit korrigieren?Glib::RefPtr
und GTKMM 3.0?Wie soll ich generell mit solchen Situationen umgehen?