On Sun, Nov 22, 2015 at 03:09:34PM +0000, Edward Bartolo wrote:
> Yes, of course, C structures can be declared that way, but the fact
> remains that the contents of the ancestor's structure are not merged
> into the heir. This means, to access a member N ancestors deep, one
> has to specify all of them in the correct order. The purpose of
> inheritance is to avoid this requirement and to make objects behave in
> a polymorphic way without actually specifying or assigning any virtual
> methods used.
There is a well-known hack in C wheereby you rely on C allocating fields
of structures independently of later fields.
Thus with
struct foo{char c, int d, float e,}
and
struct bar{char c, int d,}
(forgive me if I need semicolons here; I've used too many languages in
the alst year to remember the surface syntax)
you can rely on c and d having the same offsets in both structures, and
so you can happily cast between pointers to foo and bar as long as you
don't mess with e.
And, of course, you can have a pointer to a table of methods as the
first entry in all of these structures.
The very first versions of C++ were essentially just syntactic sugar for
this convention. That is, of course, before it metastatised like
systemd.
-- hendrik
>
>
>
> On 22/11/2015, Rainer Weikusat <rainerweikusat@???> wrote:
> > 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;
> > }
> > _______________________________________________
> > Dng mailing list
> > Dng@???
> > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
> >
> _______________________________________________
> Dng mailing list
> Dng@???
> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng