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

Posté par  (site web personnel, Mastodon) .
Étiquettes : aucune
0
10
nov.
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.
  • # Petites corrections

    Posté par  (site web personnel, Mastodon) . Évalué à 2.

    A noter que les "malloc" ne devraient pas être "castés" (honte à moi). et qu'on pourrait directement déclarer le tableau my[] du type de la pseudo-class générique ce qui évite un "cast" dans la boucle for mais qui oblige alors de "caster" my[0] et my[1].


    Et quand je dis que c'est à éviter (de faire ce genre de pseudo-polymorphisme) c'est très relatif.. car ce principe peut être très pratique et même indispensable dans des cas très précis (l'écriture de couches d'abstraction par exemple, ou de GUI).
  • # Mouais bof

    Posté par  (site web personnel) . Évalué à 1.

    Ah ouais super, à quand le ducktyping en brainfuck?

    Haypo (qui retourne à son code Python en rigolant tout seul)
  • # Vérification ?

    Posté par  . É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

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.