Object orientation in C is normally done with function pointers. That means a structure which contains not only the data for an instance but the functions to call as well.
It's the easiest way to do inheritance and polymorphism in C. By way of example, here's an object-orientd communications example.
It only has one method open
but you can see how that differs for the TCP and HTML sub-classes. By having an initialisation routine which sets the a class-specific function, you get polymorphism.
#include <stdio.h>
// The top-level class.
typedef struct _tCommClass {
int (*open)(struct _tCommClass *self, char *fspec);
} tCommClass;
// Function for the TCP class.
static int tcpOpen (tCommClass *tcp, char *fspec) {
printf ("Opening TCP: %s\n", fspec);
return 0;
}
static int tcpInit (tCommClass *tcp) {
tcp->open = &tcpOpen;
return 0;
}
// Function for the HTML class.
static int htmlOpen (tCommClass *html, char *fspec) {
printf ("Opening HTML: %s\n", fspec);
return 0;
}
static int htmlInit (tCommClass *html) {
html->open = &htmlOpen;
return 0;
}
// Test program.
int main (void) {
int status;
tCommClass commTcp, commHtml;
// Same base class but initialized to different sub-classes.
tcpInit (&commTcp);
htmlInit (&commHtml);
// Called in exactly the same manner.
status = (commTcp.open)(&commTcp, "bigiron.box.com:5000");
status = (commHtml.open)(&commHtml, "http://www.microsoft.com");
return 0;
}
A more complete answer can be found here.
In response to your comment:
I don't want the functions contained in every single instance.
You're probably right. It's unnecessary to duplicate that information when it will be the same for every instance of a single class.
There's a simple way around that. Rather than having every instance carry its own set of function pointers, you create one structure holding them for the class, then each instance gets a pointer to that structure.
That will save quite a bit of space at the (minimal) cost of having to do two levels of indirection to call a function.