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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5643923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:35:14  来源:igfitidea点击:

C++ Initializing Non-Static Member Array

c++arraysdefault-constructor

提问by Michael Hornfeck

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

我正在编辑一些旧的 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};

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.

我想让所有这些数组成为下面定义的 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
}

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?

我想在 Robot() 构造函数中初始化这六个数组的元素。除了一个一个地分配每个元素之外,还有什么办法可以做到这一点?

采纳答案by iammilind

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

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

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.

如果这是不可能的,那么像往常一样使用不同的名称声明这个数组,并memcpy()在构造函数中用于数据成员。

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

编辑:对于非静态成员,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

C++11

The array initialization has now become trivial:

数组初始化现在变得微不足道:

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

回答by andreabedini

you can either make it static, or use the new initialisation introduced in C++0x

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

回答by ildjarn

To throw one other approach into the mix (and one that doesn'ttell you to make the array data members staticas most of the other answers do – I assume youknow whether or not they should be static), here's the zero-overhead approach I use: Make staticmember 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):

将另一种方法混入其中(并且不会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())
{ }

回答by Mahesh

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::fillcan be used.

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

#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.

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

回答by Antti Huima

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.

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

回答by Serge Ballesta

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:

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

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.

因为 的第一个元素G_被显式初始化为该值,0.而所有其他元素都被初始化为零。

回答by CyberDem0n

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

回答by holtavolt

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.

不是真的,虽然我同意 stefaanv 的评论——如果它们以前是全局的,那么让它们静态会让你“容易分配”,而且它们看起来好像它们可能是 const static 一眼。

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.

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

回答by typelogic

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