160 votes

Initialisation pratique de la structure C ++

J'essaie de trouver un moyen pratique pour initialiser 'pod' C++ des structures. Maintenant, considérons la structure suivante:

struct FooBar {
  int foo;
  float bar;
};
// just to make all examples work in C and C++:
typedef struct FooBar FooBar;

Si je veux idéalement initialiser dans C (!), Je pourrais écrire tout simplement:

/* A */ FooBar fb = { .foo = 12, .bar = 3.4 }; // illegal C++, legal C

Notez que je veux éviter explicitement la notation suivante, parce qu'il me frappe comme étant fait de me casser le cou si je change quelque chose dans la structure dans l'avenir:

/* B */ FooBar fb = { 12, 3.4 }; // legal C++, legal C, bad style?

Pour obtenir le même (ou au moins similaire) en C++ comme en /* A */ exemple, j'aurais à mettre en œuvre un idiot constructeur:

FooBar::FooBar(int foo, float bar) : foo(foo), bar(bar) {}
// ->
/* C */ FooBar fb(12, 3.4);

Ce qui est bon pour l'ébullition de l'eau, mais ne convient pas pour les paresseux (la paresse est une bonne chose, non?). Aussi, il est à peu près aussi mauvais que l' /* B */ exemple, comme il ne fait pas explicitement état qui passe par les états.

Donc, ma question est fondamentalement la façon dont je peux réaliser quelque chose de similaire /* A */ ou mieux en C++? Sinon, je serais d'accord avec une explication des raisons pour lesquelles je ne devrais pas envie de le faire (c'est à dire pourquoi mon mental paradigme est mauvais).

MODIFIER

En pratique, je veux dire aussi maintenable et non redondantes.

48voto

iammilind Points 29275

Puisque style A n'est pas autorisé en C ++ et que vous ne voulez pas style B pourquoi ne pas utiliser style BX :

 FooBar fb = { /*.foo=*/ 12, /*.bar=*/ 3.4 };  // :)
 

Au moins aider dans une certaine mesure.

8voto

Matthieu M. Points 101624

Votre question est un peu difficile en raison même de la fonction:

static FooBar MakeFooBar(int foo, float bar);

peut être appelé comme:

FooBar fb = MakeFooBar(3.4, 5);

à cause de la promotion et des conversions les règles pour les types numériques intégrés. C n'a jamais été vraiment fortement typé)

En C++, ce que vous voulez, c'est réalisable, mais avec l'aide de modèles et statique assertions:

template <typename Integer, typename Real>
FooBar MakeFooBar(Integer foo, Real bar) {
  static_assert(std::is_same<Integer, int>::value, "foo should be of type int");
  static_assert(std::is_same<Real, float>::value, "bar should be of type float");
  return { foo, bar };
}

En C, vous pouvez nommer les paramètres, mais vous ne serez jamais plus loin.

D'autre part, si vous souhaitez des paramètres nommés, puis vous écrivez beaucoup de lourdeur code:

struct FooBarMaker {
  FooBarMaker(int f): _f(f) {}
  FooBar Bar(float b) const { return FooBar(_f, b); }
  int _f;
};

static FooBarMaker Foo(int f) { return FooBarMaker(f); }

// Usage
FooBar fb = Foo(5).Bar(3.4);

Et vous pouvez le poivre dans la promotion du type de protection si vous le souhaitez.

6voto

Matthias Urlichs Points 441

Si vous le pouvez, utilisez GCC. Son front.end C ++ comprend la syntaxe de l'initialiseur C.

4voto

parapura rajkumar Points 16597

Encore une autre manière en C ++ est

 struct Point
{
private:

 int x;
 int y;

public:
    Point& setX(int xIn) { x = Xin; return *this;}
    Point& setY(int yIn) { y = Yin; return *this;}

}

Point pt;
pt.setX(20).setY(20);
 

3voto

John Points 1342

Option D:

FooBar FooBarMake(int foo, float bar)

C légal, C ++ juridique. Facilement optimisable pour les POD. Bien sûr, il n'y a pas d'argument nommé, mais cela ressemble à tout C ++. Si vous voulez des arguments nommés, Objective C devrait être un meilleur choix.

Option E:

 FooBar fb;
memset(&fb, 0, sizeof(FooBar));
fb.foo = 4;
fb.bar = 15.5f;
 

C légal, C ++ juridique. Arguments nommés.

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