Saturday, January 12, 2008

Design and Implementation Idea of POLYMORPHISM in C [ non - object oriented language] Part III

Implementation

#include
#include
#include

#define MAX_SIZE_STACK 100

// here for a basic type only two methods are considered i.e. get() and print()
// and their corresponding index in the virtual_table are as
#define COUNT_METHOD 2

#define METHOD_GET 0
#define METHOD_PRINT 1

// defining general type i.e. super class for the different types

/***************** General type ***************************/

struct general_type {
// vtable is a pointer to an array of pointers to functions which takes in pointer to
// a general type and returns int
int (*(*pvtable)[COUNT_METHOD])(struct general_type *);
};

// creating an array of size COUNT_METHOD to pointers of function
typedef int (*vtable_general_type[COUNT_METHOD])(struct general_type *);

/************* methods for general_type *********************/

// constructor for general_type object

int general_type_ctor(struct general_type * this) {
// setting up the virtual table field
this->pvtable = (vtable_general_type *)malloc(sizeof(vtable_general_type));
this->pvtable[0][0] = NULL;
this->pvtable[0][1] = NULL;
return 0;
}


/******************** specific_type1 *************************/

struct specific_type1 {
int (*(*pvtable)[COUNT_METHOD])(struct specific_type1 *);



int data;
};

/************* methods for specific_type1 *********************/
typedef int (*vtable_specific_type1[COUNT_METHOD])(struct general_type *);

// constructor for specific_type1 object
int specific_type1_ctor(struct specific_type1 * this) {
// it's constructor first calls the constructor of the base class
general_type_ctor((struct general_type *) this); // typecasting "this"
this->data = 0;
/* set up vtable field */
this->pvtable = (vtable_specific_type1 *)malloc(sizeof(vtable_specific_type1));
this->pvtable[0][0] = &specific_type1_get;
this->pvtable[0][1] = &specific_type1_print;
}

int specific_type1_get(struct specific_type1 * this) {
/* Implement the input of object this */
}

int specific_type1_print(struct specific_type1 * this) {
/* Implement the output of object this */
}


/******************** specific_type2 *************************/
struct specific_type2 {
int (*(*vtable)[COUNT_METHOD])(struct specific_type2 *);
float data;
};

/************* methods for specific_type2 *********************/

// constructor for specific_type1 object
int specific_type2_ctor(struct specific_type2 * this) {
/* implement it's constructor similarly as the previous one */
}

int specific_type2_get(struct specific_type2 * this) {
/* Implement the input of object this */
}

int specific_type2_print(struct specific_type2 * this) {
/* Implement the output of object this */
}


/***********************************************************************/
/******** stack implementation using general type *********************/
/***********************************************************************/

typedef struct _stack {
// stack has pointer to an array of general type
// and also has the last index
struct general_type *list[MAX_SIZE_STACK];
int top;
} stack;


stack * stack_initialize() {
int i;
stack * s;
s = (stack *)malloc(sizeof(stack));
for(i=0; ilist[i] = (struct general_type *)malloc(sizeof(struct general_type));
}
s->top = -1;
return s;
}

struct general_type * top_of_stack(stack * s) {
struct general_type * temp;
if(s->top<0>list[s->top] == NULL )
temp = NULL;
else
temp = s->list[s->top];

return temp;
}

stack * push(stack * s, struct general_type * new) {
s->top ++;
s->list[s->top] = memcpy(s->list[s->top],new,sizeof(struct general_type));
return s;
}

stack * pop(stack * s) {
// error condition if s->top <= 0 s->top --;
return s;
}

/**********************************************************************/
/****** main program to check the working of heterogeneous stack ******/
/**********************************************************************/

int main() {
stack *s;
struct general_type * gt1, *gt2;
struct specific_type1 * st1a, * st1b; // making instances
struct specific_type2 * st2a, * st2b;

// initializing stack
s = stack_initialize();

// doing some known operations

st1a = (struct specific_type1 *)malloc(sizeof(struct specific_type1)); // allocating memory
specific_type1_ctor(st1a); // calling constructor for setting appropriate vtables

st1b = (struct specific_type1 *)malloc(sizeof(struct specific_type1));
specific_type1_ctor(st1b);

st2a = (struct specific_type2 *)malloc(sizeof(struct specific_type2)); // allocating memory
specific_type2_ctor(st2a); // calling constructor for setting appropriate vtables

// to fetch the input
(*(*st1a->pvtable)[METHOD_GET])(st1a); // to get the data of object
(*(*st2a->pvtable)[METHOD_GET])(st2a); // to get the data of object

// using polymorphism
gt1 = (struct general_type *)st1a; /* typecasting required */
gt2 = (struct general_type *)st2a; /* typecasting required */

s = push(s,gt1);
s = push(s,gt2);

/* similar working rule for other stack operations */

gt1 = top_of_stack(s);

(*(*gt1->pvtable)[METHOD_PRINT])(gt1); // to print the data of object

return 0;
}


xoxo
aL

No comments: