41 votes

Constructeur de structures en C

Donné:

 struct objStruct {
    int id;
    int value;
};

typedef struct objStruct Object;

Existe-t-il un raccourci pour allouer et initialiser l'objet, quelque chose 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 ceci :

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

56voto

JaredPar Points 333733

Dans CI, créez généralement une fonction dans le style d'un constructeur qui le fait. Par exemple (contrôle d'erreur omis par souci de concision)

 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);

32voto

Jonathan Leffler Points 299946

Dans C99 et au-delà, vous pouvez utiliser un littéral composé, qui ressemble à un cast 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 };

Les deux dernières lignes produisent le même effet - l'ordre des champs n'est pas critique. Cela utilise des « initialiseurs désignés », une autre fonctionnalité C99. Vous pouvez créer un littéral composé sans utiliser les initialiseurs désignés.

9voto

grekhss Points 145

En C, il est possible de déclarer une fonction en ligne avec le même nom que 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 cteurs C++.

3voto

nategoose Points 8011
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;
}

2voto

Jens Gustedt Points 40410

Il faut vraiment distinguer l'initialisation des static ou auto et l'allocation dynamique sur la tête. Pour le premier, faites des initialiseurs nommés, pour le second une fonction d'initialisation bien spécifiée.

Tout ce qui peut être bien emballés dans des macros vous donnent une static/auto et quelque chose de similaire à new en C++.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X