Object Oriented C Development – Part 1

C is obviously not an object oriented language. However, that does not mean it cannot be used like one. A year or more ago I wanted to learn how to structure my C code in such a way to closely resemble object oriented development so that I might gain some of the benefits of it. That being said, I found it kind of difficult to find an article on how to do this. Sure, I could guess, but as a developer fresh out of college my skills weren’t quite there. I did happen upon an article that explained how to do it, but it took quite a long time. That being said, I am writing this post in hopes that future developers might have an easier time figuring this stuff out.

I am by no means an expert in this topic, and there may be much better ways to do this, but this way works for me. I am open to suggestions on how to improve upon my method if there are any ideas out there. For the purposes of this example I am going to use a 2 dimensional vector.

The first step is to define the object and its “methods” in the header file. Typedef the object as a void pointer.

typedef void *Vector2;

We do this because we don’t want to expose the contents of the Vector2 object. Here we gain some of the information hiding benefits of object oriented development. In the C file you will define the actual members of the Vector2 class. We typedef a struct as follows:

typedef struct {
     float x;
     float y;
} _Vector2;

I precede the “private” members of my object with an “_” underscore, it helps me keep things straight.

Our next step is to define a constructor, but before we do that, I want to talk a bit about “method” naming. In OO, since the methods are packaged with the object you dont need to worry as much about naming conventions. However, in C you must worry about the names of your “methods” because methods for 2 objects cannot be named the same. I have adopted prefixing the method name with the name of the class followed by an underscore. For our Vector2 class we’ll use vector2_.

We declare the constructor in the .H file as follows:

Vector2 vector2_Create();

and define it in the .C file as such:

Vector2 vector2_Create()
{
     _Vector2 *vector2 = (_Vector2 *)malloc(sizeof(_Vector2));

     if (vector2 == NULL)
          return NULL;

     vector2->x = 0.0f;
     vector2->y = 0.0f;

     return (Vector2)vector2;
}

What we do here is allocate memory for the Vector2 object. If the pointer returned my malloc() is NULL we could not allocate memory for the object. Users of the object must check for this when they create the object. We then initialize the members to 0.0f and return it. As for the destructor, we declare it as follows:

void vector2_Destroy(Vector2 this);

And we define it as such:

void vector2_Destroy(Vector2 this)
{
     if (this == NULL)
          return;

     free (this);
}

Of course, the developer using this class must be certain to destroy that which she creates, or memory leaks will be running a muck. That is all for this part. I will go into things in depth as I add to this. This should at least get things going.

Advertisements

Father, Husband, Software Developer, Podcaster, Blogger, Gamer, and the Future Leader of the Zombie Resistance. My thoughts are my own.

Tagged with: , , , ,
Posted in C, Coding, OOP
2 comments on “Object Oriented C Development – Part 1
  1. Cole Cameron says:

    Hi Shawn,

    I’ve been playing around with this for an application at work and I have one minor change I would suggest. Using the typedef void *typename method, I find it extremely difficult to debug code using a so-called C object. Instead, I would suggest forward-declaring the struct in the header file, and then defining the members in the code-behind file.

    So, in mytype.h:
    struct my_new_type_struct;
    typedeff struct my_new_type_struct *MY_NEW_TYPE;

    And then in mytype.c:
    struct my_new_type_struct {
    int my_int_member;
    float my_float_member;
    };

    The malloc line in your initialization function then changes slightly:
    MY_NEW_TYPE mnt = (MY_NEW_TYPE)malloc(sizeof(struct my_new_type));
    ...

    I find that this still hides the members of your defined type from external routines, but when you’re debugging within your module, you are able to see the members of your new type.

    • Beautiful! I hadn’t thought of doing it like this before :). The only reason I can see for *not* doing this is if you do not want the information exposed to the debugger (closed source library for instance). I may write up a post about this :).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

%d bloggers like this: