Get started !
online LTE test
online C test

Updated or New
Site traffic (Aug-15)
GMSK modulation
Case of frequency correction burst
Solving modulation equations
One bit change
Normal duration burst



About
Feedback
Information Theory
Modulation
Multiple Access
OSI Model
Data Link layer
SS7
Word about ATM
GSM
GPRS
UMTS
WiMAX
LTE
Standard Reference
Reference books
Resources on Web
Miscellaneous
Mind Map
Perl resources
Magic MSC tool
Bar graph tool
C programming
ASCII table
Project Management
Simple Google box
HTML characters
Site traffic
Page view counter
5 6 9 , 6 5 9
another knowledge site

Object Oriented Programming using C - 2

In last article, we saw an example of polymorphism in which method of parent object is overloaded in child object. To extend the idea of abstract data type and polymorphism, can we come out with an equal_to function that can do comparison of sphere with sphere, csphere with csphere and also sphere with csphere ?!

Yes, we are talking about function like int polymorphic_equal_to( void*, void*) ! The main hurdle in implementing it in both C and C++ is that "real" type of object will not be known inside function and so we will not know exactly how to process the comparison. C++ does provide "dynamic cast" with which type of object can be determined by casting. Below is an example of such implementation in C (which can also be used for C++ if any one do not want to use dynamic cast):

File: sphere.h

  #define SPHERE_NAME "sphere"
 
  typedef struct sphere_struct sphere;
  struct sphere_struct {
   const char *name;
   int (*get_radius)(sphere*);
   int (*equal_to)(sphere*, sphere*);
   int radius;
  };
 
  void sphere_constructor(sphere* sptr, int rad);


File: csphere.h

  #include "sphere.h"
 
  #define CSPHERE_COL_LEN 4
  #define CSPHERE_NAME "csphere"
 
  typedef struct csphere_struct csphere;
  struct csphere_struct {
   const char *name;
   sphere *parent_sphere;
   int (*get_radius)(csphere*);
   const char *(*get_color)(csphere*);
   int (*equal_to)(csphere*, csphere*);
 
   char color[CSPHERE_COL_LEN];
  };
 
  void csphere_constructor(csphere* csptr, int rad, const char *col);
  static int sphere_equal_to_csphere( sphere *sptr, csphere *csptr );
  int polymorphic_equal_to( void *s1, void *s2 );



File: sphere.c

  #include "sphere.h"
 
  static int intern_get_radius(sphere *sptr);
  static int intern_equal_to(sphere *s1, sphere *s2);
 
  void sphere_constructor(sphere *sptr, int rad) {
 
    sptr->name = SPHERE_NAME;
    sptr->get_radius = intern_get_radius;
    sptr->equal_to = intern_equal_to;
    sptr->radius = rad;
 
  }
 
  int intern_get_radius(sphere *sptr) {
    return sptr->radius;
  }
 
  int intern_equal_to(sphere *s1, sphere *s2) {
    return (s1->radius == s2->radius);
  }


File: csphere.c

  #include "csphere.h"
  #include <string.h>
 
  static int intern_get_radius(csphere *csptr);
  static const char *intern_get_color(csphere *csptr);
  static int intern_equal_to(csphere *cs1, csphere *cs2);
 
  void csphere_constructor(csphere *csptr, int rad, const char *col) {
 
    csptr->name = CSPHERE_NAME;
    
    csptr->parent_sphere = (sphere*)malloc( sizeof( sphere ) );
    sphere_constructor(csptr->parent_sphere, rad);
    
    strncpy( csptr->color, col, CSPHERE_COL_LEN-1 );
    csptr->color[CSPHERE_COL_LEN-1] = '\0';
    csptr->get_color = intern_get_color;
    csptr->get_radius = intern_get_radius;
    csptr->equal_to = intern_equal_to;
  }
 
  const char *intern_get_color(csphere* csptr) {
    return csptr->color;
  }
 
  int intern_get_radius(csphere *csptr) {
    return csptr->parent_sphere->radius;
  }
 
  int intern_equal_to(csphere *cs1, csphere *cs2) {
    return( (cs1->parent_sphere->equal_to(cs1->parent_sphere, cs2->parent_sphere) ) &&
            !(strcmp(cs1->color, cs2->color))                                       );
  }
 
  int sphere_equal_to_csphere( sphere *sptr, csphere *csptr ) {
    return (sptr->radius == csptr->parent_sphere->radius);
  }
 
  int polymorphic_equal_to( void *s1, void *s2 ) {
    sphere *sptr;
    sphere *sphere1;
    csphere *csphere1;
    
    sptr = (sphere *)s1;
    if( !strcmp( sptr->name, SPHERE_NAME ) ) { /* S1-SPHERE */
      sphere1 = (sphere *)s1; 
      sptr = (sphere *)s2;
      if( !strcmp( sptr->name, SPHERE_NAME ) ) {  /* S1 & S2-SPHERE */
         return sphere1->equal_to( sphere1, (sphere*)s2 );  
      } else {
        if( !strcmp( sptr->name, CSPHERE_NAME ) ) {  /* S1-SPHERE & S2-CSPHERE */
          return sphere_equal_to_csphere( sphere1, (csphere*)s2 );  
        } 
      } 
    } else {
      if( !strcmp( sptr->name, CSPHERE_NAME ) ) { /* S1-CSPHERE */
        csphere1 = (csphere *)s1;
        sptr = (sphere *)s2;
        if( !strcmp( sptr->name, CSPHERE_NAME ) ) { /* S1 & S2-CSPHERE */
           return csphere1->equal_to( csphere1, (csphere*)s2 );  
        } else {
          if( !strcmp( sptr->name, SPHERE_NAME ) ) { /* S1-CSPHERE & S2-SPHERE */
            return sphere_equal_to_csphere( (sphere*)s2, csphere1 );  
          } 
        }       
      }
    }
    
    return 0;
  }



File: spheremain.c

  #include <stdio.h>
  #include "csphere.h"
 
  int main(void) {
 
    sphere *sphere1 = (sphere*)malloc( sizeof( sphere ) );
    csphere *csphere1 = (csphere*)malloc( sizeof( csphere ) );
    sphere *sphere2 = (sphere*)malloc( sizeof( sphere ) );
    csphere *csphere2 = (csphere*)malloc( sizeof( csphere ) );
    
    sphere_constructor(sphere1, 30);
    csphere_constructor(csphere1, 20, "red");
    sphere_constructor(sphere2, 20);
    csphere_constructor(csphere2, 30, "red");
    
    printf( "Sphere 1 of radius %d\n", sphere1->get_radius(sphere1) );
    printf( "Colored sphere 1 of radius %d and color %s\n", csphere1->get_radius(csphere1), csphere1->get_color(csphere1) );
    printf( "Sphere 2 of radius %d\n", sphere1->get_radius(sphere2) );
    printf( "Colored sphere 2 of radius %d and color %s\n", csphere2->get_radius(csphere2), csphere2->get_color(csphere2) );
 
    if( sphere1->equal_to( sphere1, sphere2 ) ) {
      printf( "Sphere 1 is equal to sphere 2\n" );
    } else {
      printf( "Sphere 1 is *not* equal to sphere 2\n" );
    }
    
    if( csphere1->equal_to( csphere1, csphere2 ) ) {
      printf( "Colored sphere 1 is equal to colored sphere 2\n" );
    } else {
      printf( "Colored sphere 1 is *not* equal to colored sphere 2\n" );
    }
    
    printf( "Using polymorphic_equal_to ....\n" );
    
    if( polymorphic_equal_to( (void*)sphere1, (void*)sphere2 ) ) {
      printf( "Sphere 1 is equal to sphere 2\n" );
    } else {
      printf( "Sphere 1 is *not* equal to sphere 2\n" );
    }
    
    if( polymorphic_equal_to( (void*)csphere1, (void*)csphere2 ) ) {
      printf( "Colored sphere 1 is equal to colored sphere 2\n" );
    } else {
      printf( "Colored sphere 1 is *not* equal to colored sphere 2\n" );
    }
    
    if( polymorphic_equal_to( (void*)csphere1, (void*)sphere2 ) ) {
      printf( "Colored sphere 1 is equal to sphere 2\n" );
    } else {
      printf( "Colored sphere 1 is *not* equal to sphere 2\n" );
    }
    
    if( polymorphic_equal_to( (void*)sphere1, (void*)csphere2 ) ) {
      printf( "Sphere 1 is equal to colored sphere 2\n" );
    } else {
      printf( "Sphere 1 is *not* equal to colored sphere 2\n" );
    }

    
    return 1;
  }

References: For OOP concepts - An introduction to OOP by Timothy Budd.

Copyright © Samir Amberkar 2010-11§

Object Oriented Programming using C « C guide Index .