C++初始化非静态成员数组

发布于 2024-11-01 10:20:06 字数 746 浏览 10 评论 0原文

我正在编辑一些旧的 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() 构造函数中初始化这六个数组的元素。除了逐一分配每个元素之外,还有其他方法可以做到这一点吗?

I am working on editing some old C++ code that uses global arrays defined like so:

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

I want to make all of these arrays private members of the Robot class defined below. However, the C++ compiler does not let me initialize data members when I declare them.

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
}

I want to initialize the elements of these six arrays in the Robot() constructor. Is there any way to do this other than assigning each element one by one?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

东风软 2024-11-08 10:20:06

如果您的要求确实允许,那么您可以将这 5 个数组作为类的静态数据成员,并在 .cpp 文件中定义时初始化它们,如下所示:

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

如果不可能,则像往常一样声明此数组使用不同的名称并使用 memcpy() 作为构造函数内的数据成员。

编辑
对于非静态成员,可以使用下面的 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}, ...
       {}
};

If your requirement really permits then you can make these 5 arrays as static data members of your class and initialize them while defining in .cpp file like below:

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

If that is not possible then, declare this arrays as usual with different name and use memcpy() for data members inside your constructor.

Edit:
For non static members, below template style can be used (for any type like int). For changing the size, simply overload number of elements likewise:

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

The array initialization has now become trivial:

class Robot
{
   private:
       int posLShd[5];
       ...
   public:
       Robot() : posLShd{0, 1, 2, 3, 4}, ...
       {}
};
2024-11-08 10:20:06

您可以将其设置为静态,或者使用 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};

you can either make it static, or use the new initialisation introduced in 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};
や莫失莫忘 2024-11-08 10:20:06

将另一种方法加入到混合中(以及一种告诉您将数组数据成员设置为静态,就像大多数其他答案一样 - 我假设 >你知道它们是否应该是静态),这是我使用的零开销方法:创建静态成员函数并让它们返回std::array>> (或 boost::array>>< /code>如果您的编译器太旧,无法提供 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())
{ }

To throw one other approach into the mix (and one that doesn't tell you to make the array data members static as most of the other answers do – I assume you know whether or not they should be static), here's the zero-overhead approach I use: Make static member functions and have them return std::array<> (or boost::array<> if your compiler is too old to come with a std:: or std::tr1:: implementation):

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())
{ }
泛泛之交 2024-11-08 10:20:06

除了逐一分配每个元素之外,还有其他方法可以做到这一点吗?

如果您希望用一些默认值填充数组的所有元素,可以使用std::fill

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

如果数组的每个元素需要填充不同的值,那么在每个索引处分配值是唯一的选择。

Is there any way to do this other than assigning each element one by one?

If you wish to fill all the elements of array with some default values, std::fill can be used.

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

If each element of the array needs to be filled with a different value, then assigning value at each index is the only option.

请你别敷衍 2024-11-08 10:20:06

将全局变量保留在代码中,然后使用 memcpy() 初始化本地数组,将全局数组的内容复制到本地数组。

Leave the globals in the code and then initialize the local arrays with memcpy(), copying the contents of the global arrays to the local ones.

诗酒趁年少 2024-11-08 10:20:06

这与当前问题仅略有相关,但它是一种特殊情况,可以完全解决重复

零初始化是 C++ 语言中数组的特例。如果初始化列表比数组短,则其余元素初始化为零。例如,重复问题的要求是将类的所有成员(包括构造函数中最后一个数组的所有元素)初始化为零:

class myprogram {
public:
    myprogram ();
private:
    double aa,bb,cc;
    double G_[2000];
};

这对于构造函数定义来说就足够了:

myprogram::myprogram():aa(0.0),bb(0.0),cc(0.0), G_{0.} {}

因为 G_ 的第一个元素是显式初始化为值 0. 并且所有其他元素均初始化为零。

This is only slightly related to the present question, but is a special case that fully addresses a duplicate.

Zero initialization is a special case for arrays in C++ language. If the initialization list is shorter than the array, the remaining elements are zero initialized. For example, the requirement for the duplicate question was to zero initialize all members of the class including all elements of the last array in constructor:

class myprogram {
public:
    myprogram ();
private:
    double aa,bb,cc;
    double G_[2000];
};

This is enough for the constructor definition:

myprogram::myprogram():aa(0.0),bb(0.0),cc(0.0), G_{0.} {}

because the first element of G_ is explicitely initialized to the value 0. and all the other elements are zero initialized.

橘虞初梦 2024-11-08 10:20:06
// 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};
// 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};
对你再特殊 2024-11-08 10:20:06

不是真的,尽管我同意 stefaanv 的评论 - 如果它们以前是全局的,那么使它们静态将为您带来“简单的分配”,并且乍一看它们似乎可能是 const static 。

如果这些值是您偶尔更改的内容,您可能会考虑在创建类时从外部文件中读取它们,这样就可以避免重新编译。

您还可以考虑使用 std::vector 而不是固定数组来实现它提供的某些功能。

Not really, although I agree with stefaanv's comment - if they were global previously, making them static would get you the "easy assignment", and they seem as though they may be const static at a glance.

If these values are something you change occasionally, you might consider reading them in from an external file on class creation, such that you can avoid recompiles.

You also might consider using std::vector instead of the fixed arrays for some of the features it provides.

方觉久 2024-11-08 10:20:06

我在这里错过了什么吗?下面的代码有效。只需声明成员并立即初始化。

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

Am I missing something here? The code below works. Simply declare the members, and initialize right away.

#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;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文