Constructeur pour les structures en C

Donné:

struct objStruct { int id; int value; }; typedef struct objStruct Object; 

Existe-t-il un raccourci pour allouer et initialiser l’object, un peu comme un constructeur C ++?
Il pourrait même s’agir d’une macro de préprocesseur. Tout ce qui rend le code plus court et plus lisible que cela:

 Object *newObj = malloc(sizeof(Object)); // successful allocation test snipped newObj->id = id++; newObj->value = myValue; 

Dans CI, créez généralement une fonction dans le style d’un constructeur. Par exemple (vérification d’erreur omise pour des raisons de brièveté)

 Object* Object_new(int id, int value) { Object* p = malloc(sizeof(Object)); p->id = id; p->value = value; return p; } ... Object* p1 = Object_new(id++, myValue); 

En C99 et au-delà, vous pouvez utiliser un littéral composé, qui ressemble à un transfert suivi d’un initialiseur entre accolades:

 int init_value = ...; int init_id = ...; Object newObj1 = (Object){ .value = init_value, .id = init_id }; Object newObj2 = (Object){ .id = init_id, .value = init_value }; 

Le même effet est obtenu sur les deux dernières lignes. L’ordre des champs n’est pas critique. C’est-à-dire l’utilisation d’initialisateurs désignés, une autre fonctionnalité du C99. Vous pouvez créer un littéral composé sans utiliser d’initialiseurs désignés.

En C, il est possible de déclarer une fonction inline avec le même nom que la structure:

 struct my { int a; }; inline struct my* my(int* a) { return (struct my*)(a); } //somewhere in code int num = 123; struct my *sample = my(&num); //somewhere in code 

Cela ressemble assez aux ctors C ++.

 struct thingy { char * label; int x; }; #define declare_thingy( name, label, val) struct thingy name = { label, val } struct thingy * new_thingy(const char * label, int val) { struct thingy * p = malloc(sizeof(struct thingy)); if (p) { p->label = label; p->val = val; } return p; } 

Il faut vraiment distinguer l’initialisation auto variables static ou auto l’allocation dynamic sur la tête. Pour le premier, faites les initialiseurs nommés, pour le second une fonction init bien spécifiée.

Tout ce qui peut être joliment emballé dans des macros vous donne une static/auto facile static/auto et quelque chose de similaire aux new en C ++.

Si vous recherchez une “émulation” orientée object sur C, je vous recommande vivement le système de types GObject [1], qui est mature et largement utilisé par GTK par exemple.

GLib [2] a aussi un bon allocateur de tranches pour les petits objects, actuellement utilisé par GNOME.

[1] Manuel de référence GObject

[2] Tranches de mémoire GLib