Faire un don ! | | style | statistiques | contactez-nous | plan | lettre d'information

Astuces.divers : [Développement] Pseudo-polymorphisme en C

Posté par Mathieu SCHROETER (page perso, ) le 10 novembre 2007
Les puristes crieront au scandale, mais c'est une manière relativement simple de faire du pseudo-polymorphisme en C. Deux pseudo-objets my_hello et my_bye de type différents sont créés dans le main. Un tableau de pointeurs void va nous permettre d'utiliser les pseudo-méthodes print(), de nos deux pseudo-objets.



La pseudo-class générique gen_t sert uniquement à "caster" la pseudo-méthode print() dans la boucle "for". Mais il faut que les méthodes des pseudo-classes myh_t et myb_t aient les déclarations des pseudo-méthodes en début de leur structure et dans le même ordre que la structure générique gen_t! J'ai mis exprès des attributs en plus dans les deux pseudo-classes afin de légitimer gen_t.



Attention car il ne faut surtout pas abuser de ce genre de code qui est de loin pas de l'ANSI (et les "cast" sont généralement à éviter). Il est là uniquement à titre de dépannage. Car si vous désirez faire de l'objet, oubliez tout de suite le C et faites du C++!





Code source :



#include <stdio.h>

#include <stdlib.h>

#include <string.h>



/* Pseudo classes */

typedef struct myh_s {

  void (*print) (void);

  int x;

} myh_t;



typedef struct myb_s {

  void (*print) (void);

  double x;

} myb_t;



/* Generic pseudo-class */

typedef struct gen_s {

  void (*print) (void);

} gen_t;





void print_hello(void) {

  printf("Hello Linuxfr users!\n");

}



void print_bye(void) {

  printf("Bye Linuxfr users!\n");

}



/* Create new pseudo-object myh_t */

myh_t *new_h(void) {

  myh_t *my;



  my = (myh_t *)malloc(sizeof(myh_t));

  my->print = print_hello;



  return my;

}



/* Create new pseudo-object myb_t */

myb_t *new_b(void) {

  myb_t *my;



  my = (myb_t *)malloc(sizeof(myb_t));

  my->print = print_bye;



  return my;

}



int main(void) {

  int i;

  myh_t *my_hello;

  myb_t *my_bye;

  void *my[2];



  /* Create pseudo-objects */

  my_hello = new_h();

  my_bye = new_b();



  my[0] = my_hello;

  my[1] = my_bye;



  /* Use pseudo-objects */

  for (i = 0; i < 2; i++)

    ((gen_t *)my[i])->print();



  /* Delete pseudo-objects */

  free(my_hello);

  free(my_bye);



  return 0;

}





La sortie est donc :



Hello Linuxfr users!

Bye Linuxfr users!




Chacun leur tour, les "print()" affichent leurs textes respectifs en fonction des pseudo-objets.

> Lire le message (3 commentaires, moyenne: 1,3).  

Vous avez demandé le commentaire #922938.

Vérification ?

Posté par CdeMills (Jabber id, ) le 15/04/2008 à 09:40. (lien). Évalué à 1.

Vi, vi, mais pour déboguer ? Si tu mélanges les types (erreur de frappe, distraction), il y a risque de corruption mémoire, et pour la trouver, ce sera galère ...

CdM