gtype: Improve documentation for G_TYPE_IS_CLASSED and interfaces

The documentation previously implicitly said in a few places that
interfaces are classed, but reading through the implementation of
`GType`, I don’t think they are. If they were, the registration of the
fundamental `G_TYPE_INTERFACE` in `gobject_init()` would specify
`G_TYPE_FLAG_CLASSED`. It only specifies `G_TYPE_FLAG_DERIVABLE`.

I think this makes sense, because you can’t subclass an interface.
Subclassing is a key property of being classed.

Tweak the `GType` tutorial to remove that implicit statement, and expand
the documentation for `G_TYPE_IS_CLASSED`.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #252
This commit is contained in:
Philip Withnall 2023-04-13 15:37:00 +01:00
parent c1e0506d86
commit 783f1b8640
4 changed files with 19 additions and 10 deletions

View File

@ -294,7 +294,7 @@ ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
memory will be freed or returned to the object pool for this type.
Once the object has been freed, if it was the last instance of the type, the type's class
will be destroyed as described in <xref linkend="gtype-instantiatable-classed"/> and
<xref linkend="gtype-non-instantiatable-classed"/>.
<xref linkend="gtype-non-instantiatable-non-classed"/>.
</para>
<para>

View File

@ -599,7 +599,7 @@ B *b;
<row>
<!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry-->
<entry>interface initialization, see
<xref linkend="gtype-non-instantiatable-classed-init"/></entry>
<xref linkend="gtype-non-instantiatable-non-classed-init"/></entry>
<entry></entry>
</row>
<row>
@ -610,7 +610,7 @@ B *b;
<row>
<entry morerows="2">Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
<entry>interface destruction, see
<xref linkend="gtype-non-instantiatable-classed-dest"/></entry>
<xref linkend="gtype-non-instantiatable-non-classed-dest"/></entry>
<entry></entry>
</row>
<row>
@ -633,8 +633,8 @@ B *b;
</sect1>
<sect1 id="gtype-non-instantiatable-classed">
<title>Non-instantiatable classed types: interfaces</title>
<sect1 id="gtype-non-instantiatable-non-classed">
<title>Non-instantiatable non-classed types: interfaces</title>
<para>
This section covers the theory behind interfaces. See
@ -649,7 +649,7 @@ B *b;
be seen as a playback interface. Once you know what they do, you can
control your CD player, MP3 player or anything that uses these symbols.
To declare an interface you have to register a non-instantiatable
classed type which derives from
non-classed type which derives from
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
<informalexample><programlisting>
#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
@ -792,7 +792,7 @@ struct _GInterfaceInfo
</programlisting></informalexample>
</para>
<sect2 id="gtype-non-instantiatable-classed-init">
<sect2 id="gtype-non-instantiatable-non-classed-init">
<title>Interface Initialization</title>
<para>
@ -937,7 +937,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
</sect2>
<sect2 id="gtype-non-instantiatable-classed-dest">
<sect2 id="gtype-non-instantiatable-non-classed-dest">
<title>Interface Destruction</title>
<para>
@ -955,7 +955,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
<para>
Again, it is important to understand, as in
<xref linkend="gtype-non-instantiatable-classed-init"/>,
<xref linkend="gtype-non-instantiatable-non-classed-init"/>,
that both <function>interface_finalize</function> and <function>base_finalize</function>
are invoked exactly once for the destruction of each implementation of an interface. Thus,
if you were to use one of these functions, you would need to use a static integer variable

View File

@ -854,7 +854,7 @@ b_method_to_call (B *obj, gint some_param)
<para>
The theory behind how GObject interfaces work is given in
<xref linkend="gtype-non-instantiatable-classed"/>; this section covers how to
<xref linkend="gtype-non-instantiatable-non-classed"/>; this section covers how to
define and implement an interface.
</para>

View File

@ -304,6 +304,15 @@ G_BEGIN_DECLS
*
* Checks if @type is a classed type.
*
* A classed type has an associated #GTypeClass which can be derived to store
* class-wide virtual function pointers and data for all instances of the type.
* This allows for subclassing. All #GObjects are classed; none of the scalar
* fundamental types built into GLib are classed.
*
* Interfaces are not classed: while their #GTypeInterface struct could be
* considered similar to #GTypeClass, and classes can derive interfaces,
* #GTypeInterface doesnt allow for subclassing.
*
* Returns: %TRUE if @type is classed
*/
#define G_TYPE_IS_CLASSED(type) (g_type_test_flags ((type), G_TYPE_FLAG_CLASSED))