From: James C Hu
Subject: Re: struct inheritence (OOP C)
Date: Thu, 22 Jan 1998 19:48:56 -0600 (CST)
Message-ID: <slrn6cfto4.ijc.jxh@lambada.cs.wustl.edu>

On Thu, 22 Jan 1998 15:23:25 -0800, Wayne O. Cochran wrote:
> I am writing some OOP code in C and am trying to decide
> on the best way to implement inheritence without abusing
> the C standard. Say I have a class POINT (implemented
> as in the structure below) and I want another class CIRCLE
> to inherit the fields of POINT, but I want to be able to
> pass instances of CIRCLE to functions that manipulate
> instances of POINT. The code below depends on exactly
> how structures lay out their fields -- The ANSI C standard
> states that the address offsets of the fields occur
> in increasing order they appear in the struct template.
> Is this abusing the C standard? I note that the X11 Xt
> widget toolkit uses a similar techinique for OOP in C.
> BTW, I didn't find this one the FAQ.
>
> typedef struct {
> int x,y;
> } POINT;
>
> typedef struct {
> POINT center;
> int radius;
> } CIRCLE;
>
> void setLocation(POINT *p, int x, int y) {
> p->x = x;
> p->y = y;
> }
>
> CIRCLE c;
> setLocation(&c, 10,15);

Except for the fact that a cast is required

setLocation((POINT *)&c, 10, 15);

this is fine. ANSI/ISO 9899-1990 6.5.2.1 states that ``a pointer to a structure object, suitably converted, points to its initial member''. Hence, a pointer to a CIRCLE in your case can be suitably converted to point to a POINT.

This question is becoming a more and more popular question lately. It may be time to update the FAQ. Comments and corrections to the following are welcome.

Q. How can I implement object-oriented (OO) inheritance in C with structures?

A. First, make sure that using an OO language (such as C++) is not a good option. The C language was not designed with OO in mind, and so facilities to support OO programming are limited. Think through just what OO features you will need, and think about how you expect to implement them in C.

That said, it is possible to implement single inheritance in C by nesting a structure inside of a structure. This techniques works since a pointer to a structure object, when suitably converted, points to its initial member. Thus, single inheritance of a ``parent'' structure is accomplished by creating a new ``child'' structure whose initial member is the same type as the ``parent''. The following example (thanks to Wayne O. Cochran) illustrates how this is done.

typedef struct {
  int x;
  int y;
} point;

typedef struct {
  point center;
  int radius;
} circle;

void init_point(point *p, int x, int y)
{
  p->x = x;
  p->y = y;
}

void init_circle(circle *c, int x, int y, int r)
{
  init_point((void *)c, x, y);
  c->radius = r;
}

In this example, we see that `circle' inherits from `point' the integer members `x' and `y'. Note that the following function is invalid

void bad_init_circle(circle *c, int x, int y, int r)
{
  c->x = x;  /* should be ((point *)c)->x = x; */
  c->y = y;  /* should be ((point *)c)->y = y; */
  c->radius = r;
}

since the pointer to circle `c' has not yet been suitably converted to point to the type of its first member.

References:
ANSI Sec. 3.5.2.1
ISO Sec. 6.5.2.1

--
James C. Hu <jxh@cs.wustl.edu> Computer Science Doctoral Student
http://www.cs.wustl.edu/~jxh/ Washington University in Saint Louis
>>>>>>>>>>>>> I use *SpamBeGone* <URL:http://www.internz.com/SpamBeGone/>