Comme vous le savez, vous ne pouvez pas faire cela. Cependant, il existe des idiomes qui permettent un effet similaire. C vous permettra de faire quelque chose de similaire à ce qu'on appelle l'idiome "pimpl" dans la conception orientée objet. Votre structure peut avoir un pointeur opaque vers une autre structure déclarée en avant qui agit comme les données privées de la structure.Les fonctions qui opèrent sur la structure, prenant la place des fonctions membres, peuvent avoir la définition complète du membre privé, et peuvent en faire usage, alors que d'autres parties du code ne peuvent pas. Par exemple:
Dans un en-tête, foo.h:
struct FooPrivate;
struct Foo {
/* public: */
int x;
double y;
/* private: */
struct FooPrivate* p;
};
extern struct Foo* Foo_Create(); /* "constructor" */
extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */
Dans la mise en œuvre, foo.c:
struct FooPrivate {
int z;
};
struct Foo* Foo_Create()
{
struct Foo* foo = malloc(sizeof(Foo));
foo->p = malloc(sizeof(FooPrivate));
foo->x = 0;
foo->y = 0;
foo->p->z = 0;
return foo;
}
void Foo_DoWhatever(struct Foo* foo)
{
foo->p->z = 4; /* Can access "private" parts of foo */
}
Dans un programme:
#include "foo.h"
int main()
{
struct Foo* foo = Foo_Create();
foo->x = 100; /* Can access "public" parts of foo */
foo->p->z = 20; /* Error! FooPrivate is not fully declared here! */
Foo_DoWhatever(foo); /* Can call "member" function */
return 0;
}
Notez le besoin d'utiliser une fonction "constructeur" afin d'allouer de la mémoire pour les données privées. Évidemment, vous devrez coupler cela avec une fonction "destructeur" spéciale afin de libérer les données privées correctement.
Ou encore, si vous souhaitez que votre struct ne pas avoir de champs publics que ce soit, vous pouvez faire l'opaque struct toute , et juste avoir l'en-tête quelque chose comme
struct Foo;
extern struct Foo* Foo_Create(); /* "constructor" */
extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */
Avec la définition réelle de struct Foo
dans foo.c, et les fonctions getter et setter sont disponibles pour toutes les propriétés auxquelles vous souhaitez donner un accès direct.
Le masquage et l'encapsulation de l'information sont antérieurs à l'OOD. –