:: Re: [DNG] Experiencing with GtkBuil…
Startseite
Nachricht löschen
Nachricht beantworten
Autor: Rainer Weikusat
Datum:  
To: dng
Betreff: Re: [DNG] Experiencing with GtkBuilder
Edward Bartolo <edbarx@???> writes:
> Is it possible to use classes and objects while using gtk2/3? I
> noticed that only functions are used and that class use is ovoided by
> prepending functions with a group string. As far as I know, C can
> still use structs that are attached to a set of data and a set of
> functions, but without inheritance and polymorphyism.


C structs can be embedded into each other which means they can 'inherit'
other structs, eg, for a totally contrived example

struct something {
    int number0, number1;
};


struct another {
    struct something parent;
        int drei;
};


Assuming

struct another *pa

the elements of the embedded struct can now be accessed as

pa->parent.number0

and a this pointer can be casted to a struct something * pointing at the
first member which can thus be passed to functions expecting such a
pointer as an argument.

Further, the relatively puny "polymorphism support" of Pascal or C++ is
easily implemented without help from the compiler. One can create
structures of function pointers like this

struct something_vtable {
    int (*calc)(struct something *);
};


embed a pointer to that into the structure. Derived 'classes' can have
their own vtable structures and hence, supply alternate functions to
execute.

This mechanism as certain tendency make C++ developers go bezerk with a
particular type of strong rage, but it's entirely usuable in practice,
although more work than having it all laid out for oneself.

Working example:

------------
#include <stdio.h>

/* metainformation */
struct something;

struct something_vtable {
    int (*calc)(struct something *);
};


/*  something */
struct something {
    struct something_vtable *vt;
    int number0, number1;
};


static int calc_something(struct something *sth)
{
    return sth->number0 + sth->number1;
}


static struct something_vtable sth_vt = {
    .calc = calc_something
};


static void init_something(struct something *sth, int n0, int n1)
{
    sth->vt = &sth_vt;
    sth->number0 = n0;
    sth->number1 = n1;
}


static int calc(struct something *sth)
{
    return sth->vt->calc(sth);
}


/*  another */
struct another {
    struct something parent;
    int drei;
};


static int calc_another(struct something *sth)
{
    struct another *ath = (void *)sth;
    return ath->drei + calc_something(sth);
}


static struct something_vtable ath_vt = {
    .calc = calc_another
};


static void init_another(struct another *ath, int n0, int n1, int d)
{
    init_something((void *)ath, n0, n1);
    ath->parent.vt = &ath_vt;
    ath->drei = d;
}


/*  example program */
void print_result(struct something *sth)
{
    printf("Result: %d\n", calc(sth));
}


int main(void)
{
    struct something sth;
    struct another ath;


    init_something(&sth, 1, 2);
    init_another(&ath, 1, 2, 3);


    print_result(&sth);
    print_result((void *)&ath);


    return 0;
}