Semi-Object Oriented C Development – Part 2

In Part 1 of “Object Oriented C Development” I talked about typedefing your “class” as a “void *”, how to define a “constructor” and how to define a “destructor”. In case you forgot, or haven’t seen it, here is the link: Object Oriented C Development – Part 2

For Part 2, I’ll talk about defining “methods”. But first, let me comment to the “Semi-” added to the title. A friend on Twitter suggested I call this series Semi-Object Oriented C Development for “truthiness’ sake”. While I think Quasi or Pseudo probably describe it better, I’ll stick with “Semi-” to make him happy.

Okay, remember the type, constructor, and destructor are declared as such in the .H file as such:

typedef void *Vector2;

Vector2 vector2_Create();
void vector2_Destroy(Vector2 this);

And the members of Vector2 are defined in the .C file as such:

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

“Methods” in this case will follow the same format as the destructor. Here is how you declare a some simple accessor methods:

float vector2_GetX(Vector2 this);
void vector2_SetX(Vector2 this, float x);
float vector2_GetY(Vector2 this);
void vector2_SetY(Vector2 this, float y);

And here is how you define them.

float vector2_GetX(Vector2 this)
     return ((_Vector2 *)this)->x;

void vector2_SetX(Vector2 this, float x)
     ((_Vector2 *)this)->x = x;

The Y methods are the same as the X (just replace x with y).

Now on to some more complex methods. Normalize() is a common method for a Vector2. This method adjusts a vector to unit length. We'll declare the method in the header file as such:

void vector2_Normalize(Vector2 this);

And we'll define it as such:

void vector2_Normalize(Vector2 this)
     _Vector2 *vec2 = ((_Vector2 *)this);
     double sizeSq = 0.0;
     float scaleFactor = 0.0f;

     assert(this != NULL); /* fyi assert.h */

     sizeSq = (vec2->x * vec2->x) + (vec2->y * vec2->y);
     if (sizeSq < 10e-20) return;

     scaleFactor = 1.0f/(float)sqrt(sizeSq);

     vec2->x *= scaleFactor;
     vec2->>y *= scaleFactor;


One notable thing about the above "method". As you can see I type cast the "this" pointer into the "_Vector2" pointer. This allows us to use the pointer in a more native way without having to type cast everything. A shortcut for this I have used is to make a macro for this operation:

#define _TVECTOR2(this) ((_Vector2 *)(this))

Doing this makes it quicker (and I think cleaner) to type cast the "this" pointer.

Another notable thing is the "assert" statement. To be honest I am not sure I am using this right as "asserts" never seemed to come up in the course of my education at BSU. I learned about them reading Steve McConnell's Code Complete 2. In this case I use them to assert that the pointer I receive is not NULL (0). If you adopt setting the void * (the type of the object) to NULL when you declare it, and set it to NULL after you destroy it, you can use it as a tool to weed out possible access violations before you get them.

That is all for part 2. I will probably go into this a little deeper as I continue on with this series. Please leave comments and let me know if you see any errors or if there is anything I can do to improve this.

I am not sure what will be in part 3 yet. I may talk about alternatives to the "void *" typedef, or inheritance, adding methods as members of the struct, etc. There are a lot of things I can cover. Parts 1 and 2 give us a basis. Any votes for Part 3?

A final note:

The contents of the Normalize method above was (for the most part) taken from Canvas.H, a module my now retired professor Dr. James L. Richards provided for a course in graphics at Bemidji State University. Giving credit where it is due :).


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

Leave a Reply

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

You are commenting using your 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