Подтвердить что ты не робот

С++ Инициализация массива нестатических членов

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

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, определенными ниже. Однако компилятор С++ не позволяет мне инициализировать элементы данных, когда я их объявляю.

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(). Есть ли способ сделать это иначе, чем назначать каждый элемент по одному?

4b9b3361

Ответ 1

Если ваше требование действительно разрешает, вы можете сделать эти 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);
  }
};

С++ 11

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

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

Ответ 2

вы можете сделать его статическим или использовать новую инициализацию, введенную в С++ 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};

Ответ 3

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

Ответ 4

Есть ли способ сделать это иначе, чем назначать каждый элемент по одному?

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

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

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

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