Glib::make_refptr_for_instance

As far as i can tell there is something wrong with this template:

template <class T_CppObject>
RefPtr<T_CppObject>
make_refptr_for_instance(T_CppObject* object)
{
  return RefPtr<T_CppObject>(object, &RefPtrDeleter<T_CppObject>);
}

because RefPtrDeleter:

template <class T_CppObject>
void RefPtrDeleter(T_CppObject* object)
{
  if (!object)
    return;

  object->unreference();
}

never calls delete, and neither does object->unreference(); so in the end C++ class, that is managed by RefPtr created using this macro is never gets deleted.

The deletion of the C++ object is more indirect than you think.

When an object of a class derived from Glib::ObjectBase is created, a callback
function is registered with a call to g_object_set_qdata_full(). When the underlying
C object (e.g. a GtkBox if the C++ object is a Gtk::Box) loses its last reference
and is finalized, the callback function is called. It will call Glib::ObjectBase::destroy_notify_()
which contains delete this.

It’s complicated, but it (almost?) always works. Have you found a case where it does
not work? A case where the C++ object is not deleted, although all references to
the underlying C object have been dropped?

I have a small project where i have inherited Gtk::Button. I noticed that when i create my child class with make_refptr_for_instance its destructor is newer called. Even when i close main application window and process exits. I had to replace make_refptr_for_instance(Args…) with Glib::RefPtr(Args…) so my destructor would be properly called. But maybe i just used gtkmm wrong so my object have some references left when process exits, i am not really proficient with gtkmm.

Gtk::Button is a widget. Don’t use Glib::RefPtr and Glib::make_refptr_for_instance()
on widgets. Have you seen the Programming with gtkmm 4 tutorial?
It hasn’t got that many examples of subclassed widgets. There is one (class PackBox : public Gtk::Box)
in the Multiple-item Containers section.
You can probably find a few more.

1 Like

Thank you for clarification.

Although Programming with gtkmm states: " If you make your own Glib::ObjectBase-derived classes with create() methods that return a Glib::RefPtr, you must use Glib::make_refptr_for_instance() in your create() methods. This function creates a std::shared_ptr with a special deleter, which handles the reference-count for the wrapped C object."
And according to
gtkmm: Gtk::Widget Class Reference Gtk::Widget derives from Glib::ObjectBase

Glib::ObjectBase-derived classes with create() methods

Widgets don’t have create() methods and protected constructors, like for instance
Gdk::Pixbuf and Gio::SimpleAction. Widgets have public constructors and no create() methods.
The description of Glib::make_refptr_for_instance() says that it shall not be used for
Gtk::Widget-derived classes. It would be good to say it elsewhere, too.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.