I have been programming in C and assembly on and off for about 4 1/2 years now
and read some very interesting articles, one of which I still use to this day
from Object Magazine by John J. Matsche, here are the rules for Object Oriented
programming in C.
BTW - demolinux rocks!!!
================================================== ===================================
Encapsulation:
1. Declare an object as a typedef struct. In-
clude declarations for the function pointers.
2. Always provide an initialization fuction. Manually
assign the object's methods to the proper function
pointers (first) within this function.
3. Include a self pointer to the object as a parameter
to each of the object's methods.
Inheritance:
1. Declare the "guts" of the object struct in a separate
#define directive. Always include, as the first item
in the list, the ancestor's definition.
2. When initializing an object, always call (statically) the
ancestor's initialization function first.
Polymorphism:
1. This is achieved, because all calls to the functions you've
created for your objects must be done via the function pointers
in your object.
================================================== ====================================
================================================== ====================================
Examples:
Listing 1.
/* Specifying a field list */
#define dwindow \
int x, y;\
int (*move)( );\
int (*draw)( );\
void (*done)( );
/* declare the object */
typedef struct {
dwindow
}twindow;
/* declare a descendant of dwindow */
#define dmsgbox dwindow \
char message[8];\
void (*getmsg)( );
/* declare descendant object */
typedef struct {
dmsgbox
}tmsgbox;
Listing 2.
/* Initializaion function */
twindow *twindow_init(twindow *self)
{
self->move = twindow_move;
self->draw = twindow_draw;
self->done = twindow_done;
/* initialize data or whatever */
return(self);
}
Listing 3.
/* Initializaton of an ancestor */
tmsgbox *tmsgbox_init(tmsgbox *self)
{
/* call to ancestor init is static */
twindow_init(self);
self->getmsg = tmsgbox_getmsg;
return(self);
}
================================================== ======================================
Note:
1. Establish some sort of naming convention when utilizing this, or
any other, programming technique. Such as, you could precede
your function (method) name with the name of its respective object
(such as the above) and underscore if you so choose.
2. Dynamically allocate and release your objects, and call your functions with
thy following syntax.
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
twindow *twobj;
twobj = twindow_init(malloc(sizeof(twindow)));
(*twobj->move)(twobj);
(*twobj->draw)(twobj);
(*twobj->done)(twobj);
free(twobj);
}
/* You guys can figure out the rest */
================================================== ========================================