Fonction virtuelle en C

Résolu
cs_cogno Messages postés 26 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 12 décembre 2009 - 8 déc. 2009 à 19:48
cs_cogno Messages postés 26 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 12 décembre 2009 - 8 déc. 2009 à 22:42
Bonjour les amis,

ma question est la suivante:

Comment simuler une fonction virtuelle en C ?

Merci

2 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 28/11/2013 à 18:17
Par fonction virtuelle on entend redéfinir une méthode dans une classe fille.
Pour simuler cela, tu te fais une structure qui comporte des pointeurs sur fonction et des éléments "normaux" (ce qu'on appelle une vtable pour "virtual table", que le C++ gère automatiquement).
Ensuite, tu fais une deuxième structure qui possède au moins les mêmes éléments, en plus d'avoir des vtables.
Lorsque tu castes, si tu as bien fait les choses, même en utilisant une classe mère, ça appellera bien une méthode de la classe enfant.

C'est très dur à expliquer, voici un exemple, simplifié pour illustrer mes dires:
#include <stdio.h>
#include <stdlib.h>

typedef void (*VirtualFunctionPointer)(void*);

typedef struct
{
  VirtualFunctionPointer pFunc;
} VTable;

struct Mother;
struct Daughter;

typedef struct
{
  VTable* pVTable;
  int i;
  float f;
} Mother;

typedef struct
{
  VTable* pVTable;
  int i;
  float f;
  char c;
} Daughter;

void mother_kikoo(void* this)
{
  printf("Mother: Kikoo %p\n", this);
}

void mother_display(void* this)
{
  Mother* _this = this;
  printf("Mother: %i %f\n", _this->i, _this->f);
}

void daughter_display(void* this)
{
  Daughter* _this = this;
  mother_display((Mother*)this);
  printf("Daughter: %i %f %c\n", _this->i, _this->f, _this->c);
}

VTable VTableArrayForMother[] =
  {
    { (VirtualFunctionPointer) mother_display },
    { (VirtualFunctionPointer) mother_kikoo }
  };

VTable VTableArrayForDaughter[] =
  {
    { (VirtualFunctionPointer) daughter_display },
    { (VirtualFunctionPointer) mother_kikoo }
  };

Mother* new_Mother(void)
{
  Mother* this = NULL;
  this = (Mother*) malloc(1 * sizeof (Mother));
  this->pVTable = VTableArrayForMother;
  return this;
}

Daughter* new_Daughter(void)
{
  Daughter* this = NULL;
  this = (Daughter*) malloc(1 * sizeof (Daughter));
  this->pVTable = VTableArrayForDaughter;
  return this;
}

int main(void)
{
  Mother* klass = new_Mother();
  Mother* klass2 = (Mother*) new_Daughter();

  klass->i = 7;
  klass->f = 34.5;
  (klass->pVTable[0].pFunc)(klass);
  (klass->pVTable[1].pFunc)(klass);
  free(klass);

  printf("\n\n");

  klass2->i = 89;
  klass2->f = 103.34;
  (klass2->pVTable[0].pFunc)(klass2);
  (klass2->pVTable[1].pFunc)(klass2);
  free(klass2);

  return 0;
}
3
cs_cogno Messages postés 26 Date d'inscription dimanche 6 décembre 2009 Statut Membre Dernière intervention 12 décembre 2009
8 déc. 2009 à 22:42
J'vais méditer ce code.. :)
3
Rejoignez-nous