繁体   English   中英

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

[英]C++ Initializing Non-Static Member Array

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

如果您的要求确实允许,那么您可以将这 5 个数组作为类的static数据成员,并在 .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}, ...
       {}
};

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

要混合使用另一种方法(并且不会像大多数其他答案那样告诉您将数组数据成员设为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())
{ }

除了一个一个地分配每个元素之外,还有什么办法可以做到这一点?

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

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

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

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

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

零初始化是 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.所有其他元素都被初始化为零。

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM