The guys from Gtkmm are comparing Glib::RefPtr
with std::auto_ptr<>
:
Glib::RefPtr
is a smartpointer. Specifically, it is a reference-counting smartpointer. You might be familiar withstd::auto_ptr<>
, which is also a smartpointer, butGlib::RefPtr<>
is much simpler, and more useful.
But for some strange reason, I can't get my work done with the RefPtr
. The same code is just fine with a auto_ptr
.
In the following code, SmartPtr
is just a placeholder for one of these two 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();
}
When compiling, I first define SmartPtr
as Glib::RefPtr
and then as 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
$
The problem is this GLib-GObject-CRITICAL
. In my real application, this isn't just a single line but a whole bunch of them. In the second version with std::auto_ptr
everything gets destructed well.
Strange enough the code it is just fine in GTK 2:
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out
$
I don't want to depend on std::auto_ptr
because it is deprecated and I also don't want to work with a raw pointer because then the destructors have to manually delete the pointers which adds extra complexity ...
My questions are:
- Why causes
Glib::RefPtr
this "critical warning" (probably a double free)? - Why does it work with gtkmm 2.4 but not in 3.0?
- Can I fix the code with
Glib::RefPtr
and gtkmm 3.0? - How should I handle such situations in general?