Pages

Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Monday, August 9, 2010

Type-casting confusions

Type casting in C++ confuses me to no end, but what confuses me even more is the traditional typecasting expression. Consider this

member (cricket_team);

Now, when I see that line out of context, I can’t make out if that is a function call or type-casting. Which makes me wonder why would someone use that when it can me done like this

(member) cricket_team;

Tuesday, August 3, 2010

Object Oriented Programming in C

If there is C++, what is the need of doing Object Oriented Programming (OOP) in C? Well I don’t have a compelling reason other than that it is a fun exercise.  So, with that in mind, I am going to show an approach to OOP in C next. It is as close to OOP but not exactly OOP - for one it is not compiler restricted programming - that is compiler won’t crib if I break the OOP rules - and two, this implementation is short on some parameters of OOP. Which I will examine as I go along the example.

Note: The programmer  should understand the underlying assumptions and should enforce the rules of programming to achieve OOP in C, as outlined below.

I will use two main features of C to attain encapsulation and function polymorphism. Namely, function pointers and static functions. Accompanied by segregation of public and private members in header files.

I start with a public header file –publicclass.h- of the class, which should be included wherever that class is needed.

typedef struct _testClass testClass;
struct _testClass {
    int publicData;
   
    void (*publicFunc)(testClass*);
};

// function to create testClass
testClass *constructClass(void);
void destructClass(testClass*);

The structure testClass  above defines public members of the class. Every function declared has to take a pointer to the structure of which it is a member. This  is done to emulate 'this', as in C++. So, that we know the object being referred to. Also constructor and a destructor functions are defined, which create and destroy the class object respectively. These are like C++ constructors/destructors in a loose sense. These have to be called the first (for constructor) and the last (for destructor) in the object life cycle. The public function pointer defined will be discussed later.

Next I declare a private header file –privateclass.h- , to encapsulate the private data of the class. This is done by exclusively including this file in the class declaration file – class.c- and not anywhere else. This is one of the user coding restrictions to enforce data encapsulation.

#include "publicclass.h"

typedef struct _itestClass itestClass;
struct _itestClass {
// public:
    testClass public;
// private:
    int privateData;
   
    void (*privateFunc)(itestClass*);
};

The structure above is called itestClass, where ‘i’ stands for internal or more appropriately private (I avoided using ‘p’ for private as to not confuse it with pointer).  This structure looks similar to the previous one but with one difference, that is, it includes the public ‘testClass’ structure on the top - it is the first member. This serves a simple purpose of simplifying the pointer arithmetic, such that the pointer to ‘public’ (of ‘testClass’) will be the pointer to ‘itestClass’. This will become clear on the actual class implementation, below. Note, that the private functions takes pointer of ‘itestClass’.

Finally, the class implementation –class.c-. It is more or less self explanatory, where both public and private functions are defined. And in constructor assigned to the created object, and the pointer to the public structure –testClass- returned.

#include "publicclass.h"
#include "privateclass.h"

static void publicFunc(testClass *this) {
    itestClass *ithis = (itestClass*)this;
   
    printf("This is publicFunc\n");

    this->publicData = 20;
    printf("From publicFunc: publicData: %d\n", this->publicData);
   
    ithis->privateData = 30;
    printf("From publicFunc: privateData: %d\n\n", ithis->privateData);
   
    ithis->privateFunc(ithis);
}

static void privateFunc(itestClass *ithis) {
    printf("This is privateFunc\n");
}

testClass *constructClass(void) {
    itestClass *pobj = (itestClass*)calloc(1, sizeof(itestClass));
   
    pobj->public.publicData = 0;
    pobj->public.publicFunc = publicFunc;
    pobj->privateData = 0;
    pobj->privateFunc = privateFunc;
    return &pobj->public;
}

void destructClass(testClass *pobj){
    if (pobj) { free(pobj); }
}

As mentioned earlier ‘this’ (pointer to class object) is used to get ‘ithis’ (pointer to internal class object). In a class declaration all the functions are ‘static’ (except the constructor and destructor), to avoid namespace pollution and achieve function polymorphism. Such that, another class can be defined with a different implementation of the functions. Apart from function polymorphism class hierarchy can also be achieved and that is left as an exercise for the reader :-).  Note: only this file includes the private header file –privateclass.h.

And lastly here is how to use the above built OOP structure in C.

#include "publicclass.h"

int main (int argc, const char * argv[]) {
   
    testClass *pobj = constructClass();

    pobj->publicData = 10;
    printf("From main: publicData: %d\n\n", pobj->publicData);
   
    // Error: not a member of obj(testClass) and itestClass is not visible
    // pobj->privateData = 20;
   
    pobj->publicFunc(pobj);
   
    destructClass(pobj);
    return 0;
}

Output.

From main: publicData: 10

This is publicFunc
From publicFunc: publicData: 20
From publicFunc: privateData: 30

This is privateFunc

 Download this example from here.

(I am no longer using line numbers to post the code. I realized that with line numbers it is difficult to make changes in the post. On a change I have to update line numbers, else leave it discontinuous.)

Thursday, July 29, 2010

C++ polymorphism

This code is to explain how polymorphism works through virtual functions and how C++ does it using VPTR and VTABLE. Please refer to my last post - C++ test code on virtual functions – to understand this better.

Code example to find out VPTR and VTABLE in C++ class. And use it to show how
polymorphism works in C++. That is same base class pointer can be used to
invoke functions of the derived class. C++ achieves this by changing the VPTR
pointer to new drived classes VTABLE.

VPTR and VTABLE usage for polymorphism in C++ Class expalined diagrammatically below. The base class object VPTR changes when base class is instantiated with that sub class, to point to the VTABLE of that sub class.

'?' - denotes VPTR will decide what subclass is currently instantiated to
the base class.

BaseClass Object
    (pobj)               SubClass_1
       |               VTABLE (vtable)
       v                     |
+------------+               v
| VPTR (vptr)|     *-->+------------+
+------------+  ?      |  VTEntry1  |------------> +------------+
| DATA1 (a)  |     *   +------------+              |  func1()   |
+------------+     |   |  VTEntry2  |--------+     |            |
| DATA2 (b)  |     |   +------------+        |     |            |
+------------+     |   |      .     |        |     +------------+
|      .     |     |   |      .     |        |
|      .     |     |   |      .     |        +---->+------------+
|      .     |     |                               |   func2()  |
|      .     |     |                               |            |
                   |                               |            |
                   |                               +------------+
                   |     SubClass_2
                   |   VTABLE (vtable)
                   |         |
                   |         v
                   +-->+------------+
                       |  VTEntry1  |------------> +------------+
                       +------------+              |  func1()   |
                       |  VTEntry2  |--------+     |            |
                       +------------+        |     |            |
                       |      .     |        |     +------------+
                       |      .     |        |
                       |      .     |        +---->+------------+
                                                   |   func2()  |
                                                   |            |
                                                   |            |
                                                   +------------+

And this is how the class hierarchy looks like in the following code.
                  +------------------+
                  |     BaseClass    |
                  +------------------+
                    /             \
                   /               \
                  /                 \
                 V                   V
+------------------+             +------------------+
|    SubClass_1    |             |    SubClass_2    |
+------------------+             +------------------+

typedef void (*func)(void); // class member function type
typedef int* ptr;           // 32 bit system pointer type

class BaseClass {
private:
    int a; // DATA1

public:
    BaseClass() : a(0) {}

    // pure virtual function
    virtual void func1() =0;
    virtual void func2() =0;
    static void deref_vtable(ptr);
};

class SubClass_1 : public BaseClass {
public:
    void func1() {
        cout << "SubClass_1::func1" << endl;
    }

    void func2() {
        cout << "SubClass_1::func2" << endl;
    }
};

class SubClass_2 : public BaseClass {
public:
    void func1() {
        cout << "SubClass_2::func1" << endl;
    }

    void func2() {
        cout << "SubClass_2::func2" << endl;
    }
};

// static function to dereference the vtable entries
void BaseClass::deref_vtable(ptr vtable) {
    func pfunc = NULL;

    // dereferencing first (VTABLE1) entry in VTABLE
    pfunc = (func)*(vtable+0);
    pfunc();

    // dereferencing second (VTABLE2) entry in VTABLE
    pfunc = (func)*(vtable+1);
    pfunc();

    return;
}

int main(int argc, char * const argv[]) {
    BaseClass *pobj = NULL;
    ptr  vptr, vtable;

    // first sub class
    pobj = new SubClass_1;
    vptr = (ptr)pobj;     // first address of obj (class) points to vptr
    vtable = (ptr)*vptr;  // dereferencing vptr to get vtable

    cout << "vptr: " << vptr << "   " << "vtable: " << vtable << endl;
    BaseClass::deref_vtable(vtable);

    delete pobj;
    cout << endl;
 
    // second sub class
    pobj = new SubClass_2;
    vptr = (ptr)pobj;     // first address of obj (class) points to vptr
    vtable = (ptr)*vptr;  // dereferencing vptr to get vtable

    cout << "vptr: " << vptr << "   " << "vtable: " << vtable << endl;
    BaseClass::deref_vtable(vtable);

    delete pobj;
    return 0;
}

Output:
vptr: 0x9934008   vtable: 0x8048cf8
SubClass_1::func1
SubClass_1::func2

vptr: 0x9934008   vtable: 0x8048ce8
SubClass_2::func1
SubClass_2::func2

polymorphtest.cpp file link

C++ virtual functions

I did this stuff while understanding virtual functions and polymorphism in C++ for job interviews. And got a chance to clean it up and comment it well (of course to be put on a blog).

This ones on virtual functions, explaining how VPTR and VTABLE work. Code is self explanatory, accompanied by a diagram.

Code example to find out VPTR and VTABLE in C++ class. And use it to probe
class virtual functions.
VPTR and VTABLE usage in C++ Class expalined diagrammatically below.

Test Class Object
     (obj)
       |             VTABLE (vtable)
       v                   |
+------------+             v
| VPTR (vptr)|------>+------------+
+------------+       |  VTEntry1  |------------> +------------+
| DATA1 (a)  |       +------------+              |  func1()   |
+------------+       |  VTEntry2  |-------+      |            |
| DATA2      |       +------------+       |      |            |
+------------+       |      .     |       |      +------------+
|      .     |       |      .     |       |
|      .     |       |      .     |       +----->+------------+
|      .     |                                   |   func2()  |
|      .     |                                   |            |
                                                 |            |
                                                 +------------+

typedef void (*func)(void); // class member function type
typedef int* ptr;           // 32 bit system pointer type

class Test {
public:
    int a; // DATA1

    Test() : a(0) {}

    virtual void func1() {
        cout << "Test::func1" << endl;
    }

    virtual void func2() {
        cout << "Test::func2" << endl;
    }
};

int main(int argc, char * const argv[]) {
    Test obj;
    int  *pdata;
    ptr  vptr, vtable;
    func pfunc = NULL;

    vptr = (ptr)&obj;     // first address of obj (class) points to vptr
    vtable = (ptr)*vptr;  // dereferencing vptr to get vtable
    pdata = (int*)((ptr)&obj+1); // this is 'a', the first member of class Test

    *pdata = 10;
    cout << "pdata (a): " << *pdata << endl;
    cout << "vptr: " << vptr << "   " << "vtable: " << vtable << endl;

    // dereferencing first (VTEntry1) entry in VTABLE
    pfunc = (func)*(vtable+0);
    pfunc();

    // dereferencing second (VTEntry2) entry in VTABLE
    pfunc = (func)*(vtable+1);
    pfunc();

    return 0;
}

Output:
pdata (a): 10
vptr: 0xbfee67d4   vtable: 0x8048a80
Test::func1
Test::func2

virtualtest.cpp file link