[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: