C ++ Инициализация массива нестатических элементов - PullRequest
15 голосов
/ 13 апреля 2011

Я работаю над редактированием некоторого старого кода C ++, который использует глобальные массивы, определенные так:

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

Я хочу сделать все эти массивы частными членами класса Robot, определенного ниже.Однако компилятор C ++ не позволяет мне инициализировать элементы данных при их объявлении.

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
}

Я хочу инициализировать элементы этих шести массивов в конструкторе Robot ().Есть ли способ сделать это, кроме как назначить каждый элемент один за другим?

Ответы [ 8 ]

15 голосов
/ 13 апреля 2011

Если ваше требование действительно позволяет, вы можете сделать эти 5 массивов как static членов данных вашего класса и инициализировать их при определении в файле .cpp, как показано ниже:

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

Если это невозможнозатем объявите этот массив как обычно с другим именем и используйте memcpy() для элементов данных внутри вашего конструктора.

Edit : Для нестатических элементов можно использовать стиль ниже template (для любого типа, например int).Для изменения размера просто перегрузите число элементов также:

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

Инициализация массива теперь стала тривиальной:

class Robot
{
   private:
       int posLShd[5];
       ...
   public:
       Robot() : posLShd{0, 1, 2, 3, 4}, ...
       {}
};
12 голосов
/ 13 апреля 2011

вы можете либо сделать его статическим, либо использовать новую инициализацию, представленную в 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};
4 голосов
/ 13 апреля 2011

Чтобы добавить еще один подход (и тот, который не говорит вам сделать элементы данных массива static, как это делают большинство других ответов - я предполагаю you знаю, должны ли они быть static), вот такой подход, который я использую с нулевыми издержкамислишком стар для реализации std:: или 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())
{ }
3 голосов
/ 13 апреля 2011

Есть ли способ сделать это, кроме как присвоить каждому элементу один за другим?

Если вы хотите заполнить все элементы массива некоторыми значениями по умолчанию, std::fill может

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

Если каждый элемент массива должен быть заполнен различным значением, тогда присвоение значения каждому индексу является единственной возможностью.

1 голос
/ 13 апреля 2011

Оставьте глобальные переменные в коде, а затем инициализируйте локальные массивы с помощью memcpy (), скопировав содержимое глобальных массивов в локальные.

0 голосов
/ 06 ноября 2018

Я что-то здесь упускаю?Код ниже работает.Просто объявите участников и сразу инициализируйте.

#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 голосов
/ 13 апреля 2011

Не совсем, хотя я согласен с комментарием stefaanv - если бы они были глобальными ранее, то, сделав их статичными, вы получили бы «простое назначение», и они с первого взгляда выглядят как статичные.

Если вы периодически изменяете эти значения, вы можете рассмотреть их чтение из внешнего файла при создании класса, чтобы избежать перекомпиляции.

Вы также можете рассмотреть возможность использования std :: vector вместо фиксированных массивов для некоторых функций, которые он предоставляет.

0 голосов
/ 13 апреля 2011
// 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};
...