Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Destruction

GObject destruction happens in two phases: dispose, then finalize. In plain C, these are both virtual functions, but peel bridges finalize to the C++ destructor. Therefore, while GObject classes in peel do not have C++ constructors, they do have C++ destructors.

Disposing

Dispose is a virtual function defined in the base GObject::Object class (GObject::Object::dispose), and you can override it much like any other vfunc:

inline void
Gizmo::Class::init ()
{
  override_vfunc_dispose<Gizmo> ();
}

inline void
Gizmo::vfunc_dispose ()
{
  /* ...tear things down... */

  parent_vfunc_dispose<Gizmo> ();
}

Generally, in dispose you should release (let go of, disconnect yourself from) any other objects that your object references, so your object becomes inert. But note that vfunc_dispose may, potentially, be invoked multiple times for the same object, so you should not crash or misbehave if it is invoked repeatedly.

If you’re keeping a reference to another object using RefPtr, you can just assign nullptr to it, which will release the object if the pointer wasn’t already null1:

class Gizmo final : public peel::GObject::Object
{
  PEEL_SIMPLE_CLASS (Gizmo, Object)

  inline void
  vfunc_dispose ();

  RefPtr<Gio::InputStream> input_stream;
};

inline void
Gizmo::vfunc_dispose ()
{
  /* release the input stream, if any */
  input_stream = nullptr;

  parent_vfunc_dispose<Gizmo> ();
}

If your class is a GTK widget that holds another widget as a direct child (and not as a template child), you should remember to unparent the child in your dispose, but only do so the first time vfunc_dispose is invoked, like this:

inline void
Gizmo::vfunc_dispose ()
{
  if (child)
    {
      child->unparent ();
      child = nullptr;
    }

  parent_vfunc_dispose<Gizmo> ();
}

Finalization

Eventually (typically, immediately following disposal), your object instance will be finalized. peel bridges finalization to the C++ destructor of your class, which generally makes things “just work”, as the destructor automatically tears down any remaining data that your object owns, such as any strings or vectors (or any RefPtr you forget to nullify in dispose).

Note that even though you don’t (and can’t) declare the C++ destructor virtual, peel will properly invoke the correct destructor of the actual dynamic type of the object, much like a virtual destructor behaves in regular C++.

Although it’s rarely needed, you can still provide an explicit destructor using the regular C++ syntax for destructors:

class Gizmo final : public peel::GObject::Object
{
  PEEL_SIMPLE_CLASS (Gizmo, Object)

protected:
  ~Gizmo ();
};

inline
Gizmo::~Gizmo ()
{
  g_print ("Finalizing a Gizmo object\n");

  /* implicitly chains up to the parent destructor here */
}

  1. assigning nullptr to a RefPtr is peel’s counterpart of g_clear_object