Re: Best practise inheritance



Hi

On Mar 20, 2017, at 3:36 PM, S. Jacobi <sjacobi mailueberfall de> wrote:

First of all, inheritance may be the wrong word here in plain c, but I
don't know how else to name it.

In different projects I see different approaches how to derive custom
widgets from existing ones. I can roughly group them into 2 to 3.

1) The header only has a typedef to make the struct opaque. All
variables needed are put into the struct in the .c file.

myType.h
typedef struct _MyType    MyType;

myType.c
struct _MyType
{
 GtkWidget    *parent;
 /* additions */
 guint         i;
 ...
};

This is unsafe, the size of an instance structure is part of ABI so it can never change without releasing a 
completely new library soname.

You can use this style but its then easy to forget that restriction, so just dont.

2a) The header defines a private struct, and all variables needed are
put into this private struct.

myType.h
typedef struct _MyTypePriv MyTypePriv;
typedef struct _MyType       MyType;

myType.c
struct _MyTypePriv
{
 GtkWidget    *parent;
 /* additions */
 guint         i;
};

struct _MyType
{
 MyTypePriv    *priv;
};

This is safe, and was a measure to ensure private details stay private while retaining instance size (before 
better approaches were developed).


2b) Similar to 2a, but the parent is put in the "main" struct, not the
private part.

myType.h
typedef struct _MyTypePriv MyTypePriv;
typedef struct _MyType       MyType;

myType.c
struct _MyTypePriv
{
 /* additions */
 guint         i;
};

struct _MyType
{
 GtkWidget    *parent
 MyTypePriv    *priv;
};


This is also legacy, occurrences of this in gtk+ proper will only exist to retain ABI compat with an older 
release where publicly exposed members already existed.

Even in the cases where the pointer is considered public, we prefer to wrap it in an explicit accessor (this 
also makes life easier for bindings using introspection).

So my first question: What is the best way here? And are there
(functional) differences between these?

Use instance private data, this will not need any priv pointer and can be done with th 
G_DEFINE_TYPE_WITH_PRIVATE() macro, and another to lookup your private data inside your C file (under the 
hood, this uses negative instance offsets with power nter arithmatic, so public and private data are on the 
same allocated memory slice)


And my second question is closely related: How to access "inherited"
properties, or call "inherited" functions? I see these variants in the
following examples, where I have:
MyType *myWidget;

There is no difference for accessing these things as inherited code or external code: do so with API (no such 
thing as "protected").

Alternatively, you can bend the rules by providing private accessors usually prefixed with _, without 
exporting these symbols in your shared library to users (gtk+ does this in many places, for strictly private 
object interactions).

Cheers,
    -Tristan

1) gtk_widget_set_name (GTK_WIDGET (myWidget), "myWidget");
2) gtk_widget_set_name (myWidget->parent, "myWidget");
3) gtk_widget_set_name (myWidget->priv->parent, "myWidget");

I am looking forward to helpful replies.
Thanks and kind regards
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]