Разрушение Glib::RefPtr приводит к ошибочным утверждениям в ядре GTK 3.

Ребята из 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, потому что он устарел, и я также не хочу с ним работать необработанный указатель, потому что тогда деструкторам приходится вручную удалять указатели, что добавляет дополнительную сложность...

Мои вопросы:

  1. Почему вызывает Glib::RefPtrэто "критическое предупреждение" (вероятно, двойное освобождение)?
  2. Почему это работает с gtkmm 2.4, но не работает с 3.0?
  3. Можно ли исправить код с помощью Glib::RefPtrи gtkmm 3.0?
  4. Как вообще поступать в таких ситуациях?

7
задан glitto 14 April 2012 в 19:17
поделиться