dimanche 25 janvier 2009

Le C orienté objet, 3ème partie


Voici un troisième exemple de « classe » écrite en langage C, cette version de distingue de ses précédentes par la présence d’une certaine forme d’encapsulation. Les développeurs qui manipuleront une instance de la classe « ClasseEncapsule » n’auront pas un accès direct aux champs de cette instance, ils devront passer par des accesseurs et des mutateurs. On peut trouver ces derniers inutiles dans la mesure où la plupart du temps ils se contentent de faire de simples affectations, mais ils permettent de masquer l’implémentation et ainsi de minimiser l’impact des modifications de la classe « ClasseEncapsule ».

ClasseEncapsule.h :

#ifndef CLASSEENCAPSULE_H_INCLUDED
#define CLASSEENCAPSULE_H_INCLUDED

typedef struct ClasseEncapsule *ClasseEncapsule;

extern void ClasseEncapsule_supprimer(ClasseEncapsule
maClasse);
extern double
ClasseEncapsule_methode1(ClasseEncapsule maClasse,double unDouble);

extern char *
ClasseEncapsule_methode2(ClasseEncapsule maClasse,int unInt, char * unCharEtoile);

extern ClasseEncapsule
ClasseEncapsule_creer(int champ1, double champ2, char * champ3);
extern int ClasseEncapsule_acceder_champ1(ClasseEncapsule maClasse);
extern double ClasseEncapsule_acceder_champ2(ClasseEncapsule maClasse);
extern char * ClasseEncapsule_acceder_champ3(ClasseEncapsule maClasse);
extern void ClasseEncapsule_muter_champ1(ClasseEncapsule maClasse, int valeur);
extern void ClasseEncapsule_muter_champ2(ClasseEncapsule maClasse,double valeur);
extern void ClasseEncapsule_muter_champ3(ClasseEncapsule maClasse,char * valeur);


#define ClasseEncapsuleUpCast(instance,instanceSousClasse, NOM_CLASSE_FILLE) \
ClasseEncapsule_muter_champ1(instance,NOM_CLASSE_FILLE##_acceder_champ1(instanceSousClasse)); \
ClasseEncapsule_muter_champ2(instance,NOM_CLASSE_FILLE##_acceder_champ2(instanceSousClasse)); \
ClasseEncapsule_muter_champ3(instance,NOM_CLASSE_FILLE##_acceder_champ3(instanceSousClasse));

#define ClasseEncapsuleDownCast(instance,instanceSousClasse, NOM_CLASSE_FILLE) \
NOM_CLASSE_FILLE##_muter_champ1(instanceSousClasse,ClasseEncapsule_acceder_champ1(instance)); \
NOM_CLASSE_FILLE##_muter_champ2(instanceSousClasse,ClasseEncapsule_acceder_champ2(instance)); \
NOM_CLASSE_FILLE##_muter_champ3(instanceSousClasse,ClasseEncapsule_acceder_champ3(instance));
#endif // CLASSEENCAPSULE_H_INCLUDED





ClasseEncapsuleImpl.h :

#ifndef CLASSEENCAPSULEIMPL_H_INCLUDED
#define CLASSEENCAPSULEIMPL_H_INCLUDED

#define ClasseEncapsule_methode1_IMPL(instanceClasseMere, unDouble) \
return instanceClasseMere->monChamp2 + (unDouble);

#define ClasseEncapsule_methode2_IMPL( instanceClasseMere, unInt,unCharEtoile) \
if(strlen(unCharEtoile) > (unInt)){\
return unCharEtoile;\
}\
return instanceClasseMere->monChamp3;

#define ClasseEncapsule_supprimer_IMPL(instanceClasseMere) \
if(instanceClasseMere!=NULL){\
free(instanceClasseMere);\
}

#define ClasseEncapsule_acceder_champ1_IMPL(instanceClasseMere) \
return instanceClasseMere->monChamp1;

#define ClasseEncapsule_acceder_champ2_IMPL(instanceClasseMere) \
return instanceClasseMere->monChamp2;

#define ClasseEncapsule_acceder_champ3_IMPL(instanceClasseMere) \
return instanceClasseMere->monChamp3;


#define ClasseEncapsule_muter_champ1_IMPL(instanceClasseMere,valeur) \
instanceClasseMere->monChamp1=valeur;


#define ClasseEncapsule_muter_champ2_IMPL(instanceClasseMere,valeur) \
instanceClasseMere->monChamp2=valeur;

#define ClasseEncapsule_muter_champ3_IMPL(instanceClasseMere,valeur) \
instanceClasseMere->monChamp3=valeur;


#endif // CLASSEENCAPSULEIMPL_H_INCLUDED






ClasseEncapsule.c :

#include
#include
#include
#include "classeencapsule.h"
#include "classeencapsuleimpl.h"

struct ClasseEncapsule
{
int monChamp1;
double monChamp2;
char* monChamp3;
};

int ClasseEncapsule_acceder_champ1(ClasseEncapsule maClasse){
ClasseEncapsule_acceder_champ1_IMPL(maClasse);
}
double ClasseEncapsule_acceder_champ2(ClasseEncapsule maClasse){
ClasseEncapsule_acceder_champ2_IMPL(maClasse);
}
char * ClasseEncapsule_acceder_champ3(ClasseEncapsule maClasse){
ClasseEncapsule_acceder_champ3_IMPL(maClasse);
}

void ClasseEncapsule_muter_champ1(ClasseEncapsule maClasse, int valeur){
ClasseEncapsule_muter_champ1_IMPL(maClasse,valeur);
}
void ClasseEncapsule_muter_champ2(ClasseEncapsule maClasse,double valeur){
ClasseEncapsule_muter_champ2_IMPL(maClasse,valeur);
}

void ClasseEncapsule_muter_champ3(ClasseEncapsule maClasse,char * valeur){
ClasseEncapsule_muter_champ3_IMPL(maClasse,valeur);
}

void ClasseEncapsule_supprimer(ClasseEncapsule maClasse){
ClasseEncapsule_supprimer_IMPL(maClasse);
}

double
ClasseEncapsule_methode1(ClasseEncapsule maClasse,double unDouble){

ClasseEncapsule_methode1_IMPL(maClasse,unDouble);
}

char *
ClasseEncapsule_methode2(ClasseEncapsule maClasse,int unInt, char * unCharEtoile){
ClasseEncapsule_methode2_IMPL(maClasse,unInt,unCharEtoile);


}




ClasseEncapsule
ClasseEncapsule_creer(int champ1, double champ2, char * champ3)
{
ClasseEncapsule monInstance=malloc(sizeof(struct ClasseEncapsule));

monInstance->monChamp1=champ1;
monInstance->monChamp2=champ2;
monInstance->monChamp3=champ3;
return monInstance;

}

Aucun commentaire: