Lorsque nous avons une instance de la classe « ClasseFille » comment la passer en paramètre à une méthode qui prend en paramètre une instance de la classe « ClasseMere » ? Grace aux deux autres macros-fonctions « ClasseMereUpCast » et « ClasseMereDownCast » qui permettent respectivement le transtypage de la classe fille vers la classe mère et inversement. Ce transtypage comme vous pourrez le constater à la lecture des sources est artificiel, de plus, il nécessite la présence d’une instance de la classe « ClasseMere ». En effet, la macro-fonction « ClasseMereUpCast » se contente d’affecter à chaque les donnée membre de l’instance de la classe « ClasseMere » la valeur de son équivalent dans la classe fille. La macro fonction « ClasseMereDownCast », fait le même type d’affectations mais dans le sens inverse (de l’instance de la classe mère vers l’instance de la classe fille). Ces transtypages, aussi artificiels soient ils, n’empêcheront pas, à priori, le compilateur de détecter les éventuels problèmes de type.
On peut bien évidement utiliser des macros-fonctions pour factoriser du code dans quasiment toutes les fonctions présentes dans les fichiers d’implémentation (pour alléger le code du constructeur par exemple).
Classemere.h :
#ifndef CLASSEMERE_H_INCLUDED
#define CLASSEMERE_H_INCLUDED
typedef struct ClasseMere *ClasseMere;
typedef struct DescripteurClasseMere DescripteurClasseMere;
struct DescripteurClasseMere
{
void (*supprimer)(ClasseMere);
double (*methode1)(ClasseMere a, double);
char*(*methode2)(ClasseMere a,int b, char *c);
};
struct ClasseMere
{
int monChamp1;
double monChamp2;
char* monChamp3;
DescripteurClasseMere* classe;
};
extern ClasseMere
ClasseMere_creer(int champ1, double champ2, char * champ3);
#define ClasseMereUpCast(instance,instanceSousClasse) \
instance->monChamp1=instanceSousClasse->monChamp1; \
instance->monChamp2=instanceSousClasse->monChamp2; \
instance->monChamp3=instanceSousClasse->monChamp3;
#define ClasseMereDownCast(instance,instanceSousClasse) \
instanceSousClasse->monChamp1=instance->monChamp1; \
instanceSousClasse->monChamp2=instance->monChamp2; \
instanceSousClasse->monChamp3=instance->monChamp3;
#endif // CLASSEMERE_H_INCLUDED
classemereimpl.h :
#ifndef CLASSEMEREIMPL_H_INCLUDED
#define CLASSEMEREIMPL_H_INCLUDED
#define ClasseMere_methode1_IMPL(instanceClasseMere, unDouble) \
return instanceClasseMere->monChamp2 + (unDouble);
#define ClasseMere_methode2_IMPL( instanceClasseMere, unInt,unCharEtoile) \
if(strlen(unCharEtoile) > (unInt)){\
return unCharEtoile;\
}\
return instanceClasseMere->monChamp3;
#define ClasseMere_supprimer_IMPL(instanceClasseMere) \
if(instanceClasseMere!=NULL){\
free(instanceClasseMere);\
}
#endif // CLASSEMEREIMPL_H_INCLUDED
classemere.c :
#include
#include
#include
#include "classemere.h"
#include "classemereimpl.h"
static void ClasseMere_supprimer(ClasseMere maClasse){
ClasseMere_supprimer_IMPL(maClasse);
}
static double
ClasseMere_methode1(ClasseMere maClasse,double unDouble){
ClasseMere_methode1_IMPL(maClasse,unDouble);
}
static char *
ClasseMere_methode2(ClasseMere maClasse,int unInt, char * unCharEtoile){
ClasseMere_methode2_IMPL(maClasse,unInt,unCharEtoile);
}
static DescripteurClasseMere*
ClasseMere_obtenir_descripteur(){
static int descripteurDejaInitalise=0; // superieur a 0 si le descripteur est deja initalise
static DescripteurClasseMere descripteur;
if(descripteurDejaInitalise==0){
descripteur.supprimer=ClasseMere_supprimer;
descripteur.methode1=ClasseMere_methode1;
descripteur.methode2=ClasseMere_methode2;
descripteurDejaInitalise++;
}
return &descripteur;
}
ClasseMere
ClasseMere_creer(int champ1, double champ2, char * champ3)
{
ClasseMere monInstance=malloc(sizeof(struct ClasseMere));
monInstance->monChamp1=champ1;
monInstance->monChamp2=champ2;
monInstance->monChamp3=champ3;
monInstance->classe=ClasseMere_obtenir_descripteur();
return monInstance;
}
classefille.h:
#ifndef CLASSEFILLE_H_INCLUDED
#define CLASSEFILLE_H_INCLUDED
typedef struct ClasseFille *ClasseFille;
typedef struct DescripteurClasseFille DescripteurClasseFille;
struct DescripteurClasseFille
{
void (*supprimer)(ClasseFille);
double (*methode1)(ClasseFille a, double);
char*(*methode2)(ClasseFille a,int b, char *c);
int (*methode3)(ClasseFille a,int b);
double (*methode4)(ClasseFille a,int b, double c);
};
struct ClasseFille
{
int monChamp1;
double monChamp2;
char* monChamp3;
int monChamp4;
double monChamp5;
DescripteurClasseFille* classe;
};
extern ClasseFille
ClasseFille_creer(int champ1, double champ2, char * champ3,int champ4,double champ5);
#define ClasseFilleUpCast(instance,instanceSousClasse) \
instance->monChamp1=instanceSousClasse->monChamp1; \
instance->monChamp2=instanceSousClasse->monChamp2; \
instance->monChamp3=instanceSousClasse->monChamp3; \
instance->monChamp4=instanceSousClasse->monChamp4; \
instance->monChamp5=instanceSousClasse->monChamp5;
#define ClasseFilleDownCast(instance,instanceSousClasse) \
instanceSousClasse->monChamp1=instance->monChamp1; \
instanceSousClasse->monChamp2=instance->monChamp2; \
instanceSousClasse->monChamp3=instance->monChamp3; \
instanceSousClasse->monChamp4=instance->monChamp4; \
instanceSousClasse->monChamp5=instance->monChamp5;
#endif // CLASSEFILLE_H_INCLUDED
classefilleimpl.h :
#ifndef CLASSEFILLEIMPL_H_INCLUDED
#define CLASSEFILLEIMPL_H_INCLUDED
#include "classemereimpl.h"
#define ClasseFille_methode3_IMPL(instanceClasseFille,b) \
return a->monChamp4 + (b);
#define ClasseFille_methode4_IMPL(instanceClasseFille,b,c) \
return a->monChamp5 + (c) + ((double) b);
#endif // CLASSEFILLEIMPL_H_INCLUDED
classefille.c :
#include
#include
#include
#include "classefille.h"
#include "classefilleimpl.h"
static void ClasseFille_supprimer(ClasseFille maClasse){
ClasseMere_supprimer_IMPL(maClasse);
}
static double
ClasseFille_methode1(ClasseFille maClasse,double unDouble){
ClasseMere_methode1_IMPL(maClasse,unDouble);
}
static char *
ClasseFille_methode2(ClasseFille maClasse,int unInt, char * unCharEtoile){
ClasseMere_methode2_IMPL(maClasse,unInt,unCharEtoile);
}
static int
ClasseFille_methode3(ClasseFille a,int b){
ClasseFille_methode3_IMPL(a,b);
}
static double
ClasseFille_methode4(ClasseFille a,int b, double c){
ClasseFille_methode4_IMPL(a,b,c);
}
static DescripteurClasseFille*
ClasseFille_obtenir_descripteur(){
static int descripteurDejaInitalise=0; // superieur a 0 si le descripteur est deja initalise
static DescripteurClasseFille descripteur;
if(descripteurDejaInitalise==0){
descripteur.supprimer=ClasseFille_supprimer;
descripteur.methode1=ClasseFille_methode1;
descripteur.methode2=ClasseFille_methode2;
descripteur.methode3=ClasseFille_methode3;
descripteur.methode4=ClasseFille_methode4;
descripteurDejaInitalise++;
}
return &descripteur;
}
ClasseFille
ClasseFille_creer(int champ1, double champ2, char * champ3,int champ4,double champ5)
{
ClasseFille monInstance=malloc(sizeof(struct ClasseFille));
monInstance->monChamp1=champ1;
monInstance->monChamp2=champ2;
monInstance->monChamp3=champ3;
monInstance->monChamp4=champ4;
monInstance->monChamp5=champ5;
monInstance->classe=ClasseFille_obtenir_descripteur();
return monInstance;
}