Skip to content

Instantly share code, notes, and snippets.

@dskinner
Created July 12, 2012 17:44
Show Gist options
  • Save dskinner/3099588 to your computer and use it in GitHub Desktop.
Save dskinner/3099588 to your computer and use it in GitHub Desktop.
Polymorphic behaviour in C
#include <stdio.h>
#include <stdlib.h>
//
typedef struct Duck Duck;
typedef void (*quack_t)(void *self);
void Duck_quack(void *self);
// Overriding original structure members means you must include everything up.
// So if I want to override `quack`, I dont need to override anything
// else. If I want to override `quacked`, I must override `quack` also.
struct Duck {
quack_t quack;
int quacked;
};
Duck *Duck_create()
{
Duck *d = malloc(sizeof(Duck));
d->quack = Duck_quack;
d->quacked = 0;
return d;
}
void Duck_destroy(Duck *duck)
{
free(duck);
}
void Duck_quack(void *self)
{
Duck *d = self;
if(d->quacked) {
printf("already quacked\n");
} else {
printf("quack\n");
}
d->quacked = 1;
}
//
typedef struct Bird Bird;
void Bird_quack(void *self);
struct Bird {
// Overrides have to align in memory so this comes first
quack_t quack;
// Specific to bird
Duck *duck; // we keep this to track quacked without overriding
int a;
};
Bird *Bird_create()
{
Bird *b = malloc(sizeof(Bird));
b->quack = Bird_quack;
Duck *d = malloc(sizeof(Duck));
b->duck = d;
b->a = 0;
return b;
}
void Bird_destroy(Bird *b)
{
free(b->duck);
free(b);
}
void Bird_quack(void *self)
{
Bird *b = self;
// just some sillyness on Bird alloc
if(b->duck->quacked) {
b->a += 20;
} else {
b->a++;
}
// here we have to account for how the super method (basically)
// also edits `quacked` but we didn't override it. So we pass
// in our struct Duck alloc so we can call the original method
// and have `quacked` available for use (essentially public).
Duck_quack(b->duck);
// can't do this since addition of `quacked` and I intentionally
// didn't track that in struct Bird
//Duck_quack(self);
// show progression of `a`
printf("a: %d\n", b->a);
}
//
void quack_it(void *obj)
{
Duck *d = obj;
d->quack(d);
}
int main(int argc, char *argv[])
{
Bird *b = Bird_create();
quack_it(b);
quack_it(b);
Duck *d = Duck_create();
quack_it(d);
Duck_destroy(d);
Bird_destroy(b);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment