This chapter focuses on the implementation of a subtype of GObject, for
example to create a custom class hierarchy, or to subclass a GTK+ widget.
Throughout the chapter, a running example of a file viewer program is used,
which has a ViewerFile class to represent a single file being
viewed, and various derived classes for different types of files with
special functionality, such as audio files. The example application also
supports editing files (for example, to tweak a photo being viewed), using
a ViewerEditable interface.
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 by almost all users of GObject, and has been refined over
multiple years of experience developing GObject-based code. If you are
writing a library, it is particularly important for you to adhere closely
to these conventions; users of your library will assume that you have.
Even if not writing a library, it will help other people who want to work
on your project.
Pick a name convention for your headers and source code and stick to it:
use a dash to separate the prefix from the typename:
viewer-file.h and viewer-file.c
(this is the convention used by Nautilus and most GNOME libraries).
use an underscore to separate the prefix from the
typename: viewer_file.h and
viewer_file.c.
Do not separate the prefix from the typename:
viewerfile.h and viewerfile.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.
The basic conventions for any header which exposes a GType are described
in the section called “Conventions”.
If you want to declare a type named ‘file’ in namespace ‘viewer’, name the
type instance ViewerFile and its class
ViewerFileClass (names are case sensitive). The
recommended method of declaring a type differs based on whether the type
is final or derivable.
Final types cannot be subclassed further, and should be the default choice
for new types — changing a final type to be derivable is always a change
that will be compatible with existing uses of the code, but the converse
will often cause problems. Final types are declared using
G_DECLARE_FINAL_TYPE,
and require a structure to hold the instance data to be declared in the
source code (not the header file).
Derivable types can be subclassed further, and their class and
instance structures form part of the public API which must not be changed
if API stability is cared about. They are declared using
G_DECLARE_DERIVABLE_TYPE:
The convention for header includes is to add the minimum number of
#include directives to the top of your headers needed
to compile that header. This
allows client code to simply #include "viewer-file.h",
without needing to know the prerequisites for
viewer-file.h.