To do OO in C, you usually do something like this:
C++ Class
---------
class foo
{
int a;
virtual void bar() { a = 3; }
virtual void abc() { a = 4; }
};
class doo : public foo
{
int b;
void bar() { b = 5; } /* overrides the original bar */
virtual void xzy() { b = 6; }
};
The C Version:
--------------
struct foo;
struct vtable_foo
{
void (*bar)(struct foo*);
void (*abc)(struct foo*);
};
struct vtable_foo __vtable_foo;
struct foo
{
struct vtable_foo *vtbl;
int a;
};
void foo_bar(struct foo *f)
{
f->a = 3;
}
void foo_abc(struct foo *f)
{
f->a = 4;
}
/* class initializer -- must be run EXACTLY ONCE before creating any
instances of foo */
void initialize_foo_ class()
{
__vtable_foo.ba r = foo_bar;
__vtable_foo.ab c = foo_abc;
}
/* constructor */
void foo_initialize( struct foo *f)
{
f->vtbl = &__vtable_fo o;
f->a = 0;
}
struct doo;
struct vtable_doo
{
void (*bar)(struct doo*);
void (*abc)(struct doo*);
void (*xyz)(struct doo*);
};
struct vtable_doo __vtable_doo;
struct doo
{
struct vtable_doo *vtbl;
int a; /* from foo */
int b;
};
void doo_bar(struct doo *d)
{
d->b = 5;
}
void doo_xyz(struct doo *d)
{
d->b = 6;
}
void initialize_doo_ class()
{
/* inherited from foo */
__vtable_doo.ba r = doo_bar; /* overriden in doo */
__vtable_doo.ab c = foo_abc;
/* new in doo */
__vtable_doo.xy z = doo_xyz;
}
void doo_initialize( struct doo *d)
{
d->vtbl = &__vtable_do o;
d->a = 0;
d->b = 0;
}
int main()
{
struct foo *f1;
struct foo *f2;
struct doo *d1;
initialize_foo_ class();
initialize_doo_ class();
d1 = malloc(sizeof(s truct doo));
doo_initialize( d1);
f1 = malloc(sizeof(s truct foo));
foo_initialize( f1);
f2 = d1;
(d1->vtbl->xyz)(d1); /* this sets d1->b to 6 */
printf("d1->b is %d\n", d1->b);
(f2->vtbl->bar)(f2); /* this sets d1->b to 5, because it is invoke via
vtable */
printf("d1->b is %d\n", d1->b);
(f1->vtbl->bar)(f1); /* this sets f1->a to 3 */
printf("d1->a is %d\n", f1->a);
return 0;
}
----end program----
The problem w/ this approach is (a) its messy and error prone, and (b)
it only supports direct single-line inheritance. If you want to use
multiple inheritance or even mixin classes (abstract classes like java
interfaces), it gets much trickier, and (c) you have to do a LOT of writing.
Also, while we're on the topic you might check out my article on
closures in C, which relates very closely to what we're doing here:
http://www-128.ibm.com/developerwork...-highfunc.html
Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017