First, this is merely an academic question. I know C is not the job for doing OOP programming, but this is more of a learning exercise for a beginner learning what's possible and what's not (or perhaps, what might be possible but is not a good idea).
Let's take the following as a starting place, where I have two different objects but I want to give each of them the same two methods: create
and print
. I've omitted any error checking, freeing, etc. just to simplify matters:
#include <stdio.h>
#include <stdlib.h>
struct Person {
char* name;
int age;
};
struct Car {
char* make;
char* model;
int year;
};
struct Person* create_person(void)
{
struct Person *new = malloc(sizeof (struct Person));
return new;
}
void print_person(struct Person* person)
{
printf("<Person: %s (%d)>\n", person->name, person->age);
}
struct Car* create_car(void)
{
struct Car *new = malloc(sizeof (struct Car));
return new;
}
void print_car(struct Car* car)
{
printf("<Car: %s - %s (%d)>\n", car->make, car->model, car->year);
}
int main(void)
{
struct Car *car = create_car();
*car = (struct Car) {.make="Chevy", .model="Eldorado", .year=2015};
print_car(car);
struct Person *person = create_person();
*person = (struct Person) {.name="Tom", .age=30};
print_person(person);
}
I would think that the first part would be to group the 'methods' into the struct itself. So then we would have:
#include <stdio.h>
#include <stdlib.h>
struct Person {
char* name;
int age;
void (*print)(struct Person*);
};
struct Car {
char* make;
char* model;
int year;
void (*print)(struct Car*);
};
void print_car(struct Car* car);
void print_person(struct Person* person);
struct Person* create_person(void)
{
struct Person *new = malloc(sizeof (struct Person));
return new;
}
void print_person(struct Person* person)
{
printf("<Person: %s (%d)>\n", person->name, person->age);
}
struct Car* create_car(void)
{
struct Car *new = malloc(sizeof (struct Car));
return new;
}
void print_car(struct Car* car)
{
printf("<Car: %s - %s (%d)>\n", car->make, car->model, car->year);
}
int main(void)
{
struct Car *car = create_car();
*car = (struct Car) {.make="Chevy", .model="Eldorado", .year=2015, .print=print_car};
car->print(car);
struct Person *person = create_person();
*person = (struct Person) {.name="Tom", .age=30, .print=print_person};
person->print(person);
}
What would be the next step in making it "more OOP like"? Perhaps using preprocessor glue and generics? What would be an example of the most OOP-like that the two objects could become? Again, I know this isn't what C is meant for, but it's more a learning experience.