Retourner aux forums || Retourner au forum Astuces.divers

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

Posté par Mathieu SCHROETER (page perso, ) le 10 novembre 2007
0
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).  

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

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

Petites corrections

Posté par Mathieu SCHROETER (page perso, ) le 10/11/2007 à 15:28. (lien). É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 Victor STINNER (page perso, ) le 12/11/2007 à 10:22. (lien). Évalué à 1.

Ah ouais super, à quand le ducktyping en brainfuck?

Haypo (qui retourne à son code Python en rigolant tout seul)

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

Revenir en haut de page || Retourner aux forums || Retourner au forum Astuces.divers