## Object construction

People often get confused when trying to construct their GObjects because of the sheer number of different ways to hook into the objects's construction process: it is difficult to figure which is the correct, recommended way.

Table 4, “g_object_new” shows what user-provided functions are invoked during object instantiation and in which order they are invoked. A user looking for the equivalent of the simple C++ constructor function should use the `instance_init` method. It will be invoked after all the parents’ `instance_init` functions have been invoked. It cannot take arbitrary construction parameters (as in C++) but if your object needs arbitrary parameters to complete initialization, you can use construction properties.

Construction properties will be set only after all `instance_init` functions have run. No object reference will be returned to the client of `g_object_new` until all the construction properties have been set.

It is important to note that object construction cannot ever fail. If you require a fallible GObject construction, you can use the GInitable and GAsyncInitable interfaces provided by the GIO library.

You should write the following code first:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)

    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
    }

    static void
    viewer_file_init (ViewerFile *self)
    {
      ViewerFilePrivate *priv = viewer_file_get_instance_private (self);

      /* initialize all public and private members to reasonable default values.
       * They are all automatically initialized to 0 to begin with. */
    }

If you need special construction properties (with `G_PARAM_CONSTRUCT_ONLY` set), install the properties in the `class_init()` function, override the `set_property()` and `get_property()` methods of the GObject class, and implement them as described by the section called “Object properties”.

Property IDs must start from 1, as 0 is reserved for internal use by GObject.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    enum
    {
      PROP_FILENAME = 1,
      PROP_ZOOM_LEVEL,
      N_PROPERTIES
    };

    static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

      object_class->set_property = viewer_file_set_property;
      object_class->get_property = viewer_file_get_property;

      obj_properties[PROP_FILENAME] =
        g_param_spec_string ("filename",
                             "Filename",
                             "Name of the file to load and display from.",
                             NULL  /* default value */,
                             G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);

      obj_properties[PROP_ZOOM_LEVEL] =
        g_param_spec_uint ("zoom-level",
                           "Zoom level",
                           "Zoom level to view the file at.",
                           0  /* minimum value */,
                           10 /* maximum value */,
                           2  /* default value */,
                           G_PARAM_READWRITE);

      g_object_class_install_properties (object_class,
                                         N_PROPERTIES,
                                         obj_properties);
    }

If you need this, make sure you can build and run code similar to the code shown above. Also, make sure your construct properties can be set without side effects during construction.

Some people sometimes need to complete the initialization of an instance of a type only after the properties passed to the constructors have been set. This is possible through the use of the `constructor()` class method as described in the section called “Object instantiation” or, more simply, using the `constructed()` class method. Note that the `constructed()` virtual function will only be invoked after the properties marked as `G_PARAM_CONSTRUCT_ONLY` or `G_PARAM_CONSTRUCT` have been consumed, but before the regular properties passed to `g_object_new()` have been set.