Wrapping a Glib::Object derived class instance into a Glib::RefPtr

I have a custom class derived from Glib::Object. It goes into a gtkmm3 application which uses glibmm-2.4 (2.66.7). I am trying to understand the right way to wrap a new instance in a factory method.

class CMyClass:
  public Glib::Object
{
public:
  virtual ~CMyClass()
  {
  }

  static Glib::RefPtr <CMyClass> Create(void)
  {
    return Glib::RefPtr <CMyClass>(new CMyClass);
  }

private:
  CMyClass() :
    Glib::ObjectBase(typeid(CMyClass))
  {

  }
};

Or should the factory method be like,

  static Glib::RefPtr <CMyClass> Create(void)
  {
    auto pInstance = new CMyClass;
    
    pInstance->reference();
    
    return Glib::RefPtr <CMyClass>(pInstance);
  }

I understand there is a Glib::make_refptr_for_instance but not in the version of glibmm I use.

NOTE: I am cross compiling the project for an embedded target where latest glibmm is not available in the SDK.

Well.. I seem to have figured it out. Please correct me if my findings are wrong.

The reason I posted this topic was because of an app crash which I strongly believed was originating around the way I was creating Glib::RefPtrs. It was indeed around the way I was creating it but not in the same part of the code I suspected.

To begin with, following code is perfectly fine.

static Glib::RefPtr <CMyClass> Create(void)
  {
    return Glib::RefPtr <CMyClass>(new CMyClass);
  }

This is because at birth every Glib::Object will have its reference count set to 1. So the constructor for Glib::RefPtr just updates its pCppObject_ member with the pointer to the newly created object.

My code was using a worker thread to perform some update task. The thread function is a static class member. Also a static std::queue <Glib::RefPtr <CMyClass>> was used to store the reference. Again a Glib::RefPtr is used since the thread might outlive the owner. The cause for the crash was the way I was pushing the reference to the queue. I was only doing,

    {
      std::lock_guard <std::mutex> oLock(m__s_oLoader_Mutex);

      m__s_vLoader_Queue.push(Glib::RefPtr <CMyClass>(this));
      m__s_bLoader_SignalThread = true;
    }

Since this constructor of Glib::RefPtr does not increment the reference count it gets decremented to 0 at the end of the thread when the entry was removed from the queue and that triggers object deletion. Thus the original owner ends up accessing a dead instance and poof.

Now I modified my code to this and all works well.

    {
      std::lock_guard <std::mutex> oLock(m__s_oLoader_Mutex);

      reference();

      m__s_vLoader_Queue.push(Glib::RefPtr <CMyClass>(this));
      m__s_bLoader_SignalThread = true;
    }

I understand that calling reference() is discouraged in the documentation but in this case it appears to be the only (or right) solution.

There is an old glibmm issue, filed in 2008, addressing just this issue:
glibmm#8 Hard to get a RefPtr<> to this.
The only solution suggested there is to do what you’ve done: Call reference().

For gtkmm4, I suggested that we should add a Glib::make_refptr_for_this(),
analogous to Glib::make_refptr_for_instance(). It has not been implemented,
mainly because no one commented on my suggestion, and I drew the conclusion
that no one was interested.