Making "Classes" in C using Function Pointers and Pseudo Closures

Who doesn’t want to write pseudo classes in C? A nice exercise is to do it once even if you plan to never do it again. Doing so you will have a greater appreciation for function pointers and what I am calling the pseudo closure idiom in C – passing a variable to emulate “private” data members. C doesn’t come with closures or almost anything for that matter. It is a very minimalist language which is, of course, one of its strengths and at times a weakness – like when a little abstraction could come in handy.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//declare "class template"
typedef struct stringClass {
        //class "attributes"
        char * chars;
        int len;
        //class "members"
        void (* set)(struct stringClass * self, char * ch);
        char * (* get)(struct stringClass * self);
        int (* length)(struct stringClass * self);
        void (* constructor)(struct stringClass * self);
        void (* destructor)(struct stringClass * self);
} * pString, stringClass;

//define class members
void set(pString self, char * ch) {
    self->len=strlen(ch);
    if(self->chars==NULL)
        self->chars=(char *)malloc(sizeof(char)*(self->len+1));
    else{
        free(self->chars);
        self->chars=(char *)malloc(sizeof(char)*(self->len+1));
    }
    strcpy(self->chars, ch);
}

int length(pString self) {
    return self->len;
}

char * get(pString self) {
    return self->chars;
}

void destructor(pString self) {
    free(self->chars);
}

void constructor(pString self) {
    //initialize class attributes
    self->len=0;
    self->chars=NULL;
    //bind the class members
    self->length=length;
    self->set=set;
    self->get=get;
    self->destructor=destructor;
}

int main(void)
{
    //instantiate class
    stringClass string;
    //bind constructor
    string.constructor=constructor;
    //call constructor with closure
    string.constructor(&string);
    //set the string with closure
    string.set(&string, "abcdef");
    //change the string with closure
    string.set(&string, "xyz");

    printf("\nString is %s\n", string.get(&string));//call get with closure
    printf("Length of string is %d\n", string.length(&string));//call length with closure

    //call destructor with closure
    string.destructor(&string);
    return 0;
}

Share: