Destructing Glib :: RefPtr causa asserções falhadas no núcleo do GTK 3

Os caras da Gtkmm sãocomparando Glib::RefPtr comstd::auto_ptr<>:

Glib::RefPtr é um smartpointer. Especificamente, é um smartpointer de contagem de referência. Você pode estar familiarizado comstd::auto_ptr<>, que também é um smartpointer, masGlib::RefPtr<> é muito mais simples e mais útil.

Mas por alguma estranha razão, eu não consigo fazer meu trabalho com oRefPtr. O mesmo código é bom com umauto_ptr.

No código a seguir,SmartPtr é apenas um espaço reservado para uma dessas duas smartpointers.

<code>#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();
}
</code>

Ao compilar, primeiro definoSmartPtr ComoGlib::RefPtr e depois comostd::auto_ptr.

<code>$ 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 
$
</code>

O problema é esseGLib-GObject-CRITICAL. Na minha aplicação real, isso não é apenas uma única linha, mas um monte deles. Na segunda versão comstd::auto_ptr tudo fica bem destruído.

Estranho o suficiente, o código está bem no GTK 2:

<code>$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out 
$
</code>

Eu não quero dependerstd::auto_ptr porque ele está obsoleto e eu também não quero trabalhar com um ponteiro bruto, porque os destruidores precisam excluir manualmente os ponteiros que adicionam complexidade extra ...

Minhas perguntas são:

Por que causasGlib::RefPtr este "aviso crítico" (provavelmente um duplo livre)?Por que funciona com o gtkmm 2.4, mas não com o 3.0?Posso corrigir o código comGlib::RefPtr e gtkmm 3.0?Como devo lidar com essas situações em geral?

questionAnswers(2)

yourAnswerToTheQuestion