object-oriented C programming
[ Jonathan Walther writes ]
-- Start of PGP signed section.
> Can you give an example of this typedef struct foo * thingum?
> I noticed nothing like it in my K&R book, and I'm not patient
> enough to read through the ANSI standard. I'm sure a lot of
> us developers would love to have this trick under our belts and
> improve our coding.
>
> Show us a definition, declaration, and usage.
okie dokie.
Note that you CANNOT DO THIS IN K&R. So you wouldn't have seen it there.
Plus, K&R exists to teach you the syntax of the language. NOT how to do
interesting things with it :-)
You have to have a fully ANSI-C compliant compiler, to allow
anonymous struct* typedefs, I believe.
I have to preface by saying that this does not LOOK like object-oriented
programming, for those people coming from a java or C++ background.
But if you think about it, it is.
Usage:
---blah.c----
#include "FooOBJ.h"
void diddle(){
FooOBJ fobj;
fobj=newFooOBJ();
setFooNumber(fobj, 1);
setFooString(fobj, "somestring");
dumpFooState(fobj);
deleteFooOBJ(fobj);
}
int main(){
diddle();
return 0;
}
------------------------------------------------------------
So there you have it. Complete object opacity.
You have opaque objects, and functions specifically to manupulate those
objects.
BTW: the caller will not be able to accidentally pass in a non
FooOBJ, because of the typedef.
This is even BETTER object opacity than a "normal" C++ class.
Why? Because callers have
**NO IDEA** what the private members really are, or how they are
implemented.
TO avoid putting private stuff in the .h file in C++, you'd have to first
write your "real" class, and then write a wrapper class for it, and only
give read access to the wrapper class.
FooOBJ.h consists of the following very simple definitions:
---FooOBJ.h--------------------------------------------------
typedef struct fooobj * FooOBJ;
FooOBJ newFooOBJ();
void setFooNumber(FooOBJ,int);
void setFooString(FooOBJ,char *);
void dumpFooState(FooOBJ); /* dumps debug contents of FooOBJ to stdout */
void deleteFooOBJ(FooOBJ);
------------------------------------------------------------
You simply cannot get better data hiding than that.
And just to spell things out and give you something to play with, here's
a sample implementation of FooOBJ.o
Note that there are quite a few different possibilities for it, and it
doesnt matter to the "blah.c" code above.
Which is what object oriented programming is all about!
---FooOBJ.c--------------------------------------------------
#include <stdio.h>
#include "FooOBJ.h"
struct fooobj {
int privateint;
char *privateString;
/* Depending on your preferences, you
* may prefer privateString to be a buffer,
* OR malloc it and free on delete.
*/
};
FooOBJ newFooOBJ(){
FooOBJ foo=(FooOBJ)malloc(sizeof(struct fooobj));
return foo;
}
void setFooNumber(FooOBJ foo,int num){
if(foo==NULL) return; /* you may chose to debugprint something
*instead
*/
foo->privateint=num;
}
void setFooString(FooOBJ foo,char *string){
/* If you malloced the string, you'll want to free() it here!!*/
if(foo==NULL) return;
foo->privateString=string;
}
void dumpFooState(FooOBJ foo){
if(foo==NULL) return;
printf("value of private int==%d\n", foo->privateint);
printf("value of private string==%s\n", foo->privateString);
}
void deleteFooOBJ(FooOBJ foo){
/* dont forget to free privateString if you malloced it here!!*/
free(foo);
}
------------------------------------------------------------
Well... how many people have just had their minds blown?
:-)
Reply to: