Fonction virtuelle en C [Résolu]

Signaler
Messages postés
26
Date d'inscription
dimanche 6 décembre 2009
Statut
Membre
Dernière intervention
12 décembre 2009
-
cs_cogno
Messages postés
26
Date d'inscription
dimanche 6 décembre 2009
Statut
Membre
Dernière intervention
12 décembre 2009
-
Bonjour les amis,

ma question est la suivante:

Comment simuler une fonction virtuelle en C ?

Merci

2 réponses

Messages postés
3804
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
30 janvier 2020
96
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;
}
Messages postés
26
Date d'inscription
dimanche 6 décembre 2009
Statut
Membre
Dernière intervention
12 décembre 2009

J'vais méditer ce code.. :)