GObject Reference Manual: How to define and implement a new GObject

## How to define and implement a new GObject

Clearly, this is one of the most common questions people ask: they just want to crank code and implement a subclass of a GObject. Sometimes because they want to create their own class hierarchy, sometimes because they want to subclass one of GTK+'s widget. This chapter will focus on the implementation of a subtype of GObject.

## Boilerplate header code

The first step before writing the code for your GObject is to write the type's header which contains the needed type, function and macro definitions. Each of these elements is nothing but a convention which is followed not only by GTK+'s code but also by most users of GObject. If you feel the need not to obey the rules stated below, think about it twice:

- If your users are a bit accustomed to GTK+ code or any GLib code, they will be a bit surprised and getting used to the conventions you decided upon will take time (money) and will make them grumpy (not a good thing)

- You must assess the fact that these conventions might have been designed by both smart and experienced people: maybe they were at least partly right. Try to put your ego aside.

It is, nevertheless, important to note that these rules generally apply to code that is meant to be called by third parties; it is perfectly possible to write a valid, self-contained GObject types without most of the boilerplate used in this tutorial; most of the boilerplate is also not strictly required if you plan to use the GObject types only through language bindings based on introspection.

Pick a name convention for your headers and source code and stick to it:

- use a dash to separate the prefix from the typename: `maman-bar.h` and `maman-bar.c` (this is the convention used by Nautilus and most GNOME libraries).

- use an underscore to separate the prefix from the typename: `maman_bar.h` and `maman_bar.c`.

- Do not separate the prefix from the typename: `mamanbar.h` and `mamanbar.c`. (this is the convention used by GTK+)

Some people like the first two solutions better: it makes reading file names easier for those with poor eyesight.

When you need some private (internal) declarations in several (sub)classes, you can define them in a private header file which is often named by appending the private keyword to the public header name. For example, one could use `maman-bar-private.h`, `maman_bar_private.h` or `mamanbarprivate.h`. Typically, such private header files are not installed.

The basic conventions for any header which exposes a GType are described in the section called “Conventions”. Most GObject-based code also obeys one of of the following conventions: pick one and stick to it.

- If you want to declare a type named bar with prefix maman, name the type instance `MamanBar` and its class `MamanBarClass` (name is case-sensitive). It is customary to declare them with code similar to the following:

      /*
       * Copyright/Licensing information.
       */

      /* inclusion guard */
      #ifndef __MAMAN_BAR_H__
      #define __MAMAN_BAR_H__

      #include <glib-object.h>
      /*
       * Potentially, include other headers on which this header depends.
       */

      /*
       * Type macros.
       */
      #define MAMAN_TYPE_BAR                  (maman_bar_get_type ())
      #define MAMAN_BAR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
      #define MAMAN_IS_BAR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
      #define MAMAN_BAR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
      #define MAMAN_IS_BAR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
      #define MAMAN_BAR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))

      typedef struct _MamanBar        MamanBar;
      typedef struct _MamanBarClass   MamanBarClass;

      struct _MamanBar
      {
        /* Parent instance structure */
        GObject parent_instance;

        /* instance members */
      };

      struct _MamanBarClass
      {
        /* Parent class structure */
        GObjectClass parent_class;

        /* class members */
      };

      /* used by MAMAN_TYPE_BAR */
      GType maman_bar_get_type (void);

      /*
       * Method definitions.
       */

      #endif /* __MAMAN_BAR_H__ */

- Types that require per-instance private data should use the G_DEFINE_TYPE_WITH_PRIVATE() macro, or use the G_ADD_PRIVATE() macro with the G_DEFINE_TYPE_WITH_CODE() or the G_DEFINE_TYPE_EXTENDED() macros. The private structure is then defined in the .c file, and can be accessed using the `get_instance_private()` function generated by the G_DEFINE_TYPE_* macros.

      struct _MamanBarPrivate
      {
        int hsize;
      };

      G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)

      static void
      maman_bar_class_init (MamanBarClass *klass)
      {
      }

      static void
      maman_bar_init (MamanBar *self)
      {
        /* maman_bar_get_instance_private() is generated by G_DEFINE_TYPE_WITH_PRIVATE()
         * above, and it's local to the current compilation unit.
         */
        MamanBarPrivate *priv = maman_bar_get_instance_private (self);

        priv->hsize = 42;
      }

- Most GNOME libraries use a pointer inside the instance structure for simpler access to the private data structure, as described by Herb Sutter in his Pimpl article (see Compilation Firewalls and The Fast Pimpl Idiom for reference). If you opt to use this idiom, you can assign the pointer inside the instance initialization function, e.g.:

      G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)

      struct _MamanBarPrivate
      {
        int hsize;
      };

      static void
      maman_bar_class_init (MamanBarClass *klass)
      {
      }

      static void
      maman_bar_init (MamanBar *self)
      {
        self->priv = maman_bar_get_instance_private (self);
        self->priv->hsize = 42;
      }

Finally, there are different header include conventions. Again, pick one and stick to it. I personally use indifferently any of the two, depending on the codebase I work on: the rule, as always, is consistency.

- Some people add at the top of their headers a number of #include directives to pull in all the headers needed to compile client code. This allows client code to simply #include "maman-bar.h".

- Other do not #include anything and expect the client to #include themselves the headers they need before including your header. This speeds up compilation because it minimizes the amount of pre-processor work. This can be used in conjunction with the re-declaration of certain unused types in the client code to minimize compile-time dependencies and thus speed up compilation.