Etant un habituer du C++ plutôt que de du C. Je me demande si il existe un moyen d'implémenter ce design pattern en C.
Par une approche typée objet par exemple, en créant des structures assimilées a des objets.
Etant un habituer du C++ plutôt que de du C. Je me demande si il existe un moyen d'implémenter ce design pattern en C.
Par une approche typée objet par exemple, en créant des structures assimilées a des objets.
On peut faire quelque chose de similiaire en gardant toute la structure secréte et travaillant avec des fonctions dédiées.Envoyé par chronos
Pour garder la structure secréte il suffit de la définir dans le .c de ton module et tes fonctions prendront en paramètre un pointeur void*.
Du coup, de l'extérieur du module, tu auras un pointeur vers ta structure mais aucun moyen de connaître sa taille, ce qu'elle contient, etc...
Ce qui veut dire qu'on ne peut pas en allouer derrière ton dos et donc on doit passer par ta fonction de création dans laquelle tu peux gérer l'idée du singleton.
Pas sûr que cela soit très conseillé par contre,
Jc
Salux
Pas besoin de passer par un void *. Cette technique suffit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 /* .h */ struct _MonTypeAbstrait; typedef struct _MonTypeAbstrait MonTypeAbstrait; MonTypeAbstrait * mta_create(void); /*...*/ /* .c */ struct _MonTypeAbstrait { int a; char * b; }; /*...*/
J'avais pensé à quelque chose comme la solution de Gruik, effectivement la solution avec du void* ne me plait pas trop![]()
Au final je vais refaire un semblant d'objet avec du C, merci pour vos réponses![]()
Aprés pour avoir un comportement de type singleton :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /*.c contentant ton destroy et ton create*/ static int iCpt = 0; int MYCLASS_Create(...) { if( iCpt == 0) { //creer iCpt++; } else //erreur //... return //code d'état } int MYCLASS_Destroy(...) { if( iCpt > 0) { //detruire iCpt--; } else //erreur //... return //code d'état }
et ça n'a rien de nouveau, c'est extrêmement fréquent en C....Envoyé par chronos
![]()
Un bon exemple de cela est le type standard FILE, qui est un type abstrait avec son constructeur fopen() et son destructeur fclose().Envoyé par souviron34
Encore que je préfère garder le terme "destructeur" pour le C++, RAII oblige : Pour moi, le destructeur est ce qui est supposé être appelé automatiquement à la fin du bloc (dans le cas d'objets locaux), ce qui est impossible en C.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
oui et de manière générale (pour info au PO) ce qu'on appelle la POO peut être effectuée dans tous les langages, et l'a été d'ailleurs depuis très longtemps dans des langages comme C, Fortran, et même l'assembleur pour tout un tas d'applications.
La formalisation objet est d'usage relativement récent, mais les concepts sont pratiquement utilisés depuis les débuts de l'informatique : la plupart des gens qui faisaient les programmes étaient des utlisateurs (en science par exemple), et donc manipulaient des "concepts" d'objets : un programme de traitement d'images en Fortran est un programme OO.
bah tu peux toujours t'arranger pour le faire, non ?Envoyé par Médinoc
Je ne vois pas trop comment, en tout cas.
À part en remplaçant les fins de bloc, les break, et les return (sans compter les goto) par des macros, mais dans ce cas cela empêche d'utiliser le } comme fin de bloc...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Oui, j'admet que le vocabulaire que j'ai utilise etait imprecis. Constructeur et destructeur ont des proprietes plus etendues en C++, par exemple. C'etait juste pour faire une simple analogie, sans autre pretention...Envoyé par Médinoc
Bah une fonction Destroy_Struct (void *Struct)Envoyé par Médinoc
ça peut même être une fonction totalement générale, pour peu que dans Struct tu mettes toujours un type. Et cette fonction fera un switch sur le type pour détruire les champs appropriés...
Mais peut-être que j'ai pas tout compris à la notion de destructeurs...
Non le problème est ici :Envoyé par souviron34
Jc
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 { MonTypeAbstrait a;/* Normalement on voudrait que le constructeur soit appelé ici, impossible de facon transparente en C*/ /* blabla */ } /* Normalement on voudrait que le destructeur soit appelé ici, impossible de facon transparente en C*/
OK dans ce cas oui... je comprends.
Partager