С++ Инициализация массива нестатических членов
Я работаю над редактированием старого кода на С++, который использует глобальные массивы, определенные следующим образом:
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(). Есть ли способ сделать это иначе, чем назначать каждый элемент по одному?
Ответы
Ответ 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 вместо фиксированных массивов для некоторых функций, которые он предоставляет.