web-dev-qa-db-fra.com

C++ Initialisation d'un groupe de membres non statiques

Je travaille actuellement sur l'édition de vieux code C++ utilisant des tableaux globaux définis comme suit:

int posLShd[5] = {250, 330, 512, 600, 680};
int posLArm[5] = {760, 635, 512, 320, 265};
int posRShd[5] = {765, 610, 512, 440, 380};
int posRArm[5] = {260, 385, 512, 690, 750};
int posNeck[5] = {615, 565, 512, 465, 415};
int posHead[5] = {655, 565, 512, 420, 370};

Je souhaite que tous ces tableaux constituent des membres privés de la classe Robot définie ci-dessous. Cependant, le compilateur C++ ne me permet pas d'initialiser les membres de données lorsque je les déclare.

class Robot
{
   private:
       int posLShd[5];
       int posLArm[5];
       int posRShd[5];
       int posRArm[5];
       int posNeck[5];
       int posHead[5];
   public:
       Robot();
       ~Robot();
};

Robot::Robot()
{
   // initialize arrays
}

Je souhaite initialiser les éléments de ces six tableaux dans le constructeur Robot (). Y a-t-il un moyen de faire cela autre que d'assigner chaque élément un par un?

15
Michael Hornfeck

Si votre besoin le permet vraiment, vous pouvez créer ces 5 tableaux en tant que membres de données static de votre classe et les initialiser lors de la définition dans un fichier .cpp comme ci-dessous:

class Robot
{
  static int posLShd[5];
  //...
};
int Robot::posLShd[5] = {250, 330, 512, 600, 680}; // in .cpp file

Si cela n'est pas possible, déclarez ces tableaux comme d'habitude avec un nom différent et utilisez memcpy() pour les membres de données à l'intérieur de votre constructeur.

Edit : Pour les membres non statiques, un style inférieur à template peut être utilisé (pour tout type tel que int). Pour changer la taille, il suffit simplement de surcharger le nombre d'éléments:

template<size_t SIZE, typename T, T _0, T _1, T _2, T _3, T _4>
struct Array
{
  Array (T (&a)[SIZE])
  {
    a[0] = _0;
    a[1] = _1;
    a[2] = _2;
    a[3] = _3;
    a[4] = _4;
  }
};

struct Robot
{
  int posLShd[5];
  int posLArm[5];
  Robot()
  {
    Array<5,int,250,330,512,600,680> o1(posLShd);
    Array<5,int,760,635,512,320,265> o2(posLArm);
  }
};

C++ 11

L'initialisation du tableau est maintenant devenue triviale:

class Robot
{
   private:
       int posLShd[5];
       ...
   public:
       Robot() : posLShd{0, 1, 2, 3, 4}, ...
       {}
};
15
iammilind

vous pouvez le rendre statique ou utiliser la nouvelle initialisation introduite dans C++ 0x

class Robot
{
private:
  int posLShd[5];
  static int posLArm[5];
  // ...
public:
  Robot() :
    posLShd{250, 330, 512, 600, 680} // only C++0x                                                                                     
  {}

  ~Robot();
};

int Robot::posLArm[5] = {760, 635, 512, 320, 265};
12
andreabedini

Pour jeter une autre approche dans la combinaison (et une autre qui ne vous dit de rendre les membres de données du tableau static comme le font la plupart des autres réponses - je suppose vous savez si ou non ils devraient être static), voici l’approche zéro-overhead que j’utilise: Modifie les fonctions membres static et les renvoie (renvoie std::array<> (ou boost::array<> si votre compilateur est trop ancien pour pouvoir être implémenté avec std:: ou std::tr1::):

class Robot
{
    static std::array<int, 5> posLShd_impl() { std::array<int, 5> x = {{ 250, 330, 512, 600, 680 }}; return x; }
    static std::array<int, 5> posLArm_impl() { std::array<int, 5> x = {{ 760, 635, 512, 320, 265 }}; return x; }
    static std::array<int, 5> posRShd_impl() { std::array<int, 5> x = {{ 765, 610, 512, 440, 380 }}; return x; }
    static std::array<int, 5> posRArm_impl() { std::array<int, 5> x = {{ 260, 385, 512, 690, 750 }}; return x; }
    static std::array<int, 5> posNeck_impl() { std::array<int, 5> x = {{ 615, 565, 512, 465, 415 }}; return x; }
    static std::array<int, 5> posHead_impl() { std::array<int, 5> x = {{ 655, 565, 512, 420, 370 }}; return x; }

    std::array<int, 5> posLShd;
    std::array<int, 5> posLArm;
    std::array<int, 5> posRShd;
    std::array<int, 5> posRArm;
    std::array<int, 5> posNeck;
    std::array<int, 5> posHead;
public:
    Robot();
};

Robot::Robot()
  : posLShd(posLShd_impl()),
    posLArm(posLArm_impl()),
    posRAhd(posRAhd_impl()),
    posRArm(posRArm_impl()),
    posNeck(posNeck_impl()),
    posHead(posHead_impl())
{ }
4
ildjarn

Y a-t-il un moyen de faire cela autre que d'assigner chaque élément un par un?

Si vous souhaitez remplir tous les éléments du tableau avec des valeurs par défaut, vous pouvez utiliser std::fill.

#include <algorithm>

// ...
Robot::Robot()
{
    std::fill(posLShd, posLShd+5, 13 ) ; // 13 as the default value

    // Similarly work on with other arrays too.
}

Si chaque élément du tableau doit être rempli avec une valeur différente, l'attribution d'une valeur à chaque index est la seule option.

3
Mahesh

Laissez les globales dans le code, puis initialisez les tableaux locaux avec memcpy (), en copiant le contenu des tableaux globaux dans les tableaux locaux.

1
Antti Huima

Est-ce que j'ai râté quelque chose? Le code ci-dessous fonctionne. Il suffit de déclarer les membres et d’initialiser immédiatement.

#include <iostream>

class Robot {
  public:
  int posLShd[5] = {250, 330, 512, 600, 680};
  int posLArm[5] = {760, 635, 512, 320, 265};
  int posRShd[5] = {765, 610, 512, 440, 380};
  int posRArm[5] = {260, 385, 512, 690, 750};
  int posNeck[5] = {615, 565, 512, 465, 415};
  int posHead[5] = {655, 565, 512, 420, 370};
  public:
    Robot() {}
    ~Robot() {}
};

int main () {
  Robot obj;
  for (int i = 0;i < 5;i++) {
    std::cout << obj.posRArm[i] << std::endl;
  }
}
0
typelogic
// class definition with incomplete static member could be in a header file
Class Robot {
    static const int posLShd[5];
....
// this needs to be placed in a single translation unit only
const int Robot::posLShd[5] = {250, 330, 512, 600, 680};
0
CyberDem0n

Pas vraiment, bien que je sois d'accord avec le commentaire de stefaanv - s'ils étaient globaux auparavant, les rendre statiques vous donneraient la "tâche facile", et ils semblent être statiques d'un seul coup.

Si vous modifiez occasionnellement ces valeurs, vous pouvez envisager de les lire à partir d'un fichier externe lors de la création de la classe, de manière à éviter les recompilations.

Vous pouvez également envisager d'utiliser std :: vector à la place des tableaux fixes pour certaines des fonctionnalités qu'il fournit.

0
holtavolt