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?
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);
}
};
L'initialisation du tableau est maintenant devenue triviale:
class Robot
{
private:
int posLShd[5];
...
public:
Robot() : posLShd{0, 1, 2, 3, 4}, ...
{}
};
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};
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())
{ }
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.
Laissez les globales dans le code, puis initialisez les tableaux locaux avec memcpy (), en copiant le contenu des tableaux globaux dans les tableaux locaux.
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;
}
}
// 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};
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.