Die Jungs von Gtkmm sind comparingGlib::RefPtr
mit std::auto_ptr<>
:Destructing Glib :: RefPtr verursacht gescheitert Behauptungen in der GTK 3 Kern
Glib::RefPtr
ein Intelligenter Zeiger ist. Insbesondere ist es ein Referenzzähler Smartpointer. Sie kennen vielleichtstd::auto_ptr<>
, die auch ein Smartpointer ist, aberGlib::RefPtr<>
ist viel einfacher und nützlicher.
Aber aus irgendeinem seltsamen Grund kann ich meine Arbeit nicht mit der RefPtr
erledigen. Der gleiche Code ist in Ordnung mit einem auto_ptr
.
Im folgenden Code ist SmartPtr
nur ein Platzhalter für einen dieser beiden Smartpointers.
#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();
}
Beim Kompilieren definiere ich zunächst SmartPtr
als Glib::RefPtr
und dann als std::auto_ptr
.
$ 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
$
Das Problem ist dieses GLib-GObject-CRITICAL
. In meiner realen Anwendung ist dies nicht nur eine einzelne Zeile, sondern eine ganze Reihe von ihnen. In der zweiten Version mit std::auto_ptr
wird alles gut zerstört.
Seltsam genug, um den Code, um es in GTK nur gut 2:
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out
$
Ich mag nicht auf std::auto_ptr
abzuhängen, weil es veraltet ist, und ich will auch nicht mit einem rohen Zeiger arbeiten, weil dann haben die Destruktoren manuell die Zeiger zu löschen, die zusätzliche Komplexität hinzufügt ...
Meine Fragen sind:
- Warum verursacht
Glib::RefPtr
diese „critica l warning "(wahrscheinlich ein Doppel kostenlos)? - Warum funktioniert es mit gtkmm 2.4 aber nicht in 3.0?
- Kann ich den Code mit
Glib::RefPtr
und gtkmm 3.0 beheben? - Wie soll ich generell mit solchen Situationen umgehen?
Danke für die Klärung. – glitto
Verwendet 'Glib :: RefPtr' nicht die interne' GObject' Referenzzählung? –
@ el.pescado [Überprüfen Sie die Dokumentation] (https://developer.gnome.org/glibmm/stable/classGlib_1_1RefPtr.html#details): "_RefPtr <> kann jede Klasse speichern, die reference() - und referenz() -Methoden hat , und dessen Destruktor ist kein except (der Standard für Destruktoren). In gtkmm, das ist alles aus Glib :: ObjectBase abgeleitet, wie Gdk :: Pixmap._ "Also ja. Es ist ein intrusiver Smart-Pointer, der nur für gepackte 'GObjects' gedacht ist, die ihre bereits vorhandene Referenzzählung nutzen. Anstatt die eigenen 'GObject' damit zu verpacken, habe ich den Eindruck, dass es nur ein Implementierungsdetail der' mm' Bibliotheken ist. –