oop - Object orient program in C - List -
below program,
#include<stddef.h> #include<stdlib.h> #include<string.h> #include<stdio.h> #define initial_array_size 10 typedef struct{ int *a; int lastitem; //location of lastest element stored in array int size; //size of array }list; void newlist(list **lptr, int size){ *lptr = malloc(sizeof(list)); (*lptr)->a = calloc(size, sizeof(int)); (*lptr)->lastitem = -1; (*lpr)->size =0; } list* insertitem(list *lptr, int newitem){ if(lptr->lastitem + 1 == lptr->size){ list *newlptr = null; newlist(&newlptr, 2*lptr->size); memcpy(newlptr->a, lptr->a, (lptr->lastitem)+1); newlptr->lastitem = lptr->lastitem; newlptr->size = 2*lptr->size; newlptr->a[++(newlptr->lastitem)] = newitem; free(lptr); return newlptr; } lptr->a[++(lptr->lastitem)] = newitem; return lptr; } int main(void){ list *lptr = null; newlist(&lptr, initial_array_size); lptr = insertitem(lptr, 6); for(int i=0; < initial_array_size;i++){ printf("item: %d\n", lptr->a[i]); } printf("last item value: %d", lptr->lastitem); }
written implement list
using c array.
above code written follow abstraction.
how ensure encapsultion , polymorphism, in code?
encapsulation, abstraction, , polymorphism. because these 3 things blur together, meanings fuzzy, , they're kinda difficult in c, here's how i'm defining them answer.
encapsulation restricts, or in case of c discourages, knowledge of how underlying thing works. ideally data , methods bundled together.
abstraction hides complexity user, through defined interface applicable multiple scenarios.
polymorphism allows same interface used multiple types.
they build on each other. generally, encapsulation allows abstraction allows polymorphism.
first, let's start encapsulation violation.
for(int i=0; < initial_array_size;i++){ printf("item: %d\n", lptr->a[i]); }
initial_array_size
not part of lptr
. it's external data. if pass lptr
around, initial_array_size
won't go it. loop violates encapsulation. list not encapsulated. size should detail either part of list struct or not necessary @ all.
you add size struct , use iterate.
for(int i=0; < lptr->size; i++){ printf("item: %d\n", lptr->a[i]); }
but still has user poking @ struct details. avoid add iterator , user never knows size @ all. the c++ vector interface more awkward because c lacks method calls.
listiter iter; int *value; /* associate iterator list */ listiterinit(&iter, lptr); /* listiternext returns pointer can use null stop */ /* otherwise can't store 0 */ while( value = listiternext(&iter) ) { printf("item: %d\n", *value); }
now struct has full control on how things iterate , how stores things.
this iterator interface inspired gnome lib hash tables.
this iterator interface provides abstraction. we've removed details struct. it's thing iterate through. don't need know how data stored or how there or if it's stored @ all. generated on fly know. beauty of iterator pattern.
...except still need know type. can fixed in 2 ways. first telling list how big each element is. rather modifying yours, let's @ how gnome lib arrays .
garray *garray = g_array_new (false, false, sizeof (gint)); (i = 0; < 10000; i++) { g_array_append_val (garray, i); }
the array told store things sizeof(gint)
, remembers. other array operations encapsulated in function. getting element out encapsulated.
gint g_array_index(garray, gint, 5);
this done clever macro typecasting you.
the second option store data pointers. i'll leave exercise @ gnome lib's pointer arrays.
and @ that? have polymorphism. single array struct can handle data of types.
this isn't particularly easy in c. involves macro juggling. it's @ things gnome lib get, conceptually, how it's done. maybe try practice , understanding.
but production use things gnome lib. there's tremendous number of edge cases , little details they've thought through.
Comments
Post a Comment