I ragazzi di Gtkmm sono comparingGlib::RefPtr
con std::auto_ptr<>
:Distruzione Glib :: RefPtr provoca fallito affermazioni nel nucleo GTK 3
Glib::RefPtr
è una smart pointer. In particolare, è uno smartpointer conteggio di riferimento. Si potrebbe avere familiarità constd::auto_ptr<>
, che è anche uno smartpointer, maGlib::RefPtr<>
è molto più semplice e più utile.
Ma per qualche strano motivo, non riesco a terminare il lavoro con lo RefPtr
. Lo stesso codice va bene con uno auto_ptr
.
Nel seguente codice, SmartPtr
è solo un segnaposto per uno di questi due smartpoint.
#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();
}
Quando si compila, in primo luogo ho definisco SmartPtr
come Glib::RefPtr
e poi come 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
$
Il problema è questo GLib-GObject-CRITICAL
. Nella mia vera applicazione, questa non è una singola riga ma un intero gruppo di essi. Nella seconda versione con std::auto_ptr
tutto viene distrutto bene.
abbastanza strano il codice è proprio bene in GTK 2:
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out
$
Non voglio dipendere da std::auto_ptr
perché è deprecato e ho anche non voglio lavorare con un puntatore cruda perché poi i distruttori devono eliminare manualmente i puntatori che aggiunge ulteriore complessità ...
le mie domande sono:
- Perché provoca
Glib::RefPtr
questa "critica l avvertimento "(probabilmente un doppio libero)? - Perché funziona con gtkmm 2.4 ma non in 3.0?
- Posso correggere il codice con
Glib::RefPtr
e gtkmm 3.0? - Come devo gestire tali situazioni in generale?
Grazie per aver chiarito questo. – glitto
Non 'Glib :: RefPtr' utilizza il conteggio dei riferimenti interno' GObject'? –
@ el.pescado [Controlla la documentazione] (https://developer.gnome.org/glibmm/stable/classGlib_1_1RefPtr.html#details): "_RefPtr <> può memorizzare qualsiasi classe che abbia metodi reference() e unreference() e il cui distruttore è senza eccezioni (il default per i distruttori). In gtkmm, questo è tutto derivato da Glib :: ObjectBase, come Gdk :: Pixmap._ "Quindi, sì. È un puntatore intelligente intrusivo destinato esclusivamente a 'GObject's avvolti, sfruttando il conteggio dei riferimenti preesistente. Piuttosto che avvolgere il proprio 'GObject's con esso, ho l'impressione che sia solo un dettaglio di implementazione delle librerie' mm'. –