PDA

View Full Version : OOP in C



whistlenm1
01-24-2002, 07:07 PM
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 */

================================================== ========================================

Stoned_Coder
01-24-2002, 08:13 PM
You cannot do encapsulation in c. You cannot stop me accessing the data without going through member funcs because it is public access.You can only approximate encapsulation and hope programmers behave themselves ( they never do!!)

QuestionC
01-25-2002, 02:38 AM
*shrug* What's the last time you accessed the elements of a FILE struct?

And if you were really adamant about it, you could just have the public definition of the struct be an array of chars of the appropriate size, and let the function itself use a cast that only it has access to to treat the struct as a struct. I mean, it's hardly seems worthwhile, but it's still possible.

Trying to duplicate the syntax of C++ isn't a good idea in C, personally. Many of the things that C++ can handle with it's preprocessor, are handled at run-time here.