Ребята из Gtkmm сравниваютGlib::RefPtr
с std::auto_ptr
:
Glib::RefPtr
— это умный указатель. В частности, это смарт-пойнтер с подсчетом ссылок. Возможно, вы знакомы сstd::auto_ptr
, который также является умным указателем, ноGlib::RefPtr
намного проще и полезнее.
Но по какой-то странной причине я не могу работать с RefPtr
. Тот же самый код прекрасно работает с auto_ptr
.
В следующем коде SmartPtr
является просто заполнителем для одного из этих двух умных указателей.
#include
#include
#include
struct WindowHolder {
SmartPtr 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();
}
При компиляции я сначала определяю SmartPtr
как Glib::RefPtr
, а затем как 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
$
Проблема в следующем GLib-GObject-CRITICAL
. В моем реальном приложении это не просто одна строка, а целая их куча. Во второй версии с std::auto_ptr
все хорошо деструктируется.
Достаточно странно, что в GTK 2 код работает нормально:
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out
$
Я не хочу зависеть от std::auto_ptr
, потому что он устарел, и я также не хочу с ним работать необработанный указатель, потому что тогда деструкторам приходится вручную удалять указатели, что добавляет дополнительную сложность...
Мои вопросы:
Glib::RefPtr
это "критическое предупреждение" (вероятно, двойное освобождение)?Glib::RefPtr
и gtkmm 3.0?