19

次のように定義されたグローバル配列を使用する古い 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
}

これら 6 つの配列の要素を Robot() コンストラクターで初期化したいと考えています。各要素を1つずつ割り当てる以外にこれを行う方法はありますか?

4

9 に答える 9

22

要件が本当に許される場合は、これらの 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}, ...
       {}
};
于 2011-04-13T03:17:03.237 に答える
12

静的にするか、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};
于 2011-04-13T03:20:06.437 に答える
5

ミックスに別のアプローチを1つ投入する(そして、他のほとんどの回答がそうであるように、配列データメンバーを作成するように指示しないアプローチ-それらが必要かどうかを知っていると仮定します)、ここにゼロオーバーヘッドのアプローチがありますI使用:メンバー関数を作成し、それらを返すようにします(または、コンパイラが古すぎてor実装が付属していない場合):staticstaticstaticstd::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())
{ }
于 2011-04-13T05:45:37.773 に答える
3

各要素を1つずつ割り当てる以外にこれを行う方法はありますか?

配列のすべての要素をいくつかのデフォルト値で埋めたい場合は、std::fill使用できます。

#include <algorithm>

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

    // Similarly work on with other arrays too.
}

配列の各要素に異なる値を入力する必要がある場合は、各インデックスに値を割り当てることが唯一のオプションです。

于 2011-04-13T03:20:44.267 に答える
1

コードにグローバルを残してから、ローカル配列を memcpy() で初期化し、グローバル配列の内容をローカル配列にコピーします。

于 2011-04-13T03:18:03.653 に答える
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;
  }
}
于 2018-11-06T00:17:45.517 に答える
0
// 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};
于 2011-04-13T03:18:22.540 に答える
0

そうではありませんが、stefaanvのコメントには同意しますが、以前はグローバルだった場合、静的にすると「簡単な割り当て」が得られ、一見すると const static のように見えます。

これらの値をときどき変更する場合は、再コンパイルを避けるために、クラスの作成時に外部ファイルから値を読み込むことを検討してください。

std::vector が提供する機能の一部については、固定配列の代わりに std::vector を使用することを検討することもできます。

于 2011-04-13T03:19:07.707 に答える