I do not know if this is what you need exactly, but to achieve the purpose you ask, I would do the following:
File "object.h"
:
typedef struct obj_instance obj_instance;
typedef struct Object_vtable {
void (*Set)(obj_instance *, int);
int (*Get)(obj_instance *);
int (*Equals)(obj_instance *, obj_instance *);
obj_instance *(*New)();
void (*Free)();
} Object_vtable;
extern Object_vtable Object;
void object_init();
File "object.c"
:
import "object.h"
typedef struct obj_instance {
int value;
} obj_instance;
Object_vtable Object;
void Set(obj_instance *instance, int value) {
instance->value = value;
}
int Get(obj_instance *instance) {
return instance->value;
}
int Equals(obj_instance *a, obj_instance *b) {
return a->value == b->value;
}
obj_instance *New() {
obj_instance *instance = (obj_instance *) malloc(sizeof(obj_instance));
instance->value = 0;
return instance;
}
void Free(obj_instance *instance) {
free(instance);
}
void object_init() {
Object.New = New;
Object.Free = Free;
Object.Equals = Equals;
Object.Get = Get;
Object.Set = Set;
}
The idea here is to use a vtable , basically a structure that contains multiple pointers to functions. This is analogous to a class and each of these function pointers is analogous to a method.
The Object
structure is of type Object_vtable
, and there are only one of these statically declared. It serves as the definition of a class.
malloc
exists within object.c
. But the attempt to do this in main.c
will go awry because the object.h
header only contains typedef struct obj_instance obj_instance
. Attempting to access the value
attribute directly on main.c
will also give compile error (it is private). Thus, when parsing main.c
, the compiler will know that there is a structure called obj_instance
, but it will not know the content of it, and therefore will not know its size, so sizeof
of malloc
will fail. This information will only be available to the compiler within object.c
and will only appear to the program as a whole in the linking step.
This is still quite primitive in turning C into an object-oriented language. There is still no concept of subclasses, neither polymorphism nor interfaces, although you already have something that will become a constructor, a destructor and some methods. It is also possible to have an idea how to implement the concept of public and private, since in this resulting code, the value
attribute is private and the methods are public. Methods of type is_instance
and get_class
will also be useful later, as well as making the structures that represent classes are themselves objects themselves. That's all, you'll implement later.