arrays 변수 - 정적 멤버 배열 초기화 C++




static (8)

나는 이렇게 정의 된 전역 배열을 사용하는 오래된 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 클래스의 private 멤버를 모두 배열로 만들고 싶습니다. 그러나 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 () 생성자에서이 6 개의 배열 요소를 초기화하려고합니다. 각 요소를 하나씩 할당하는 것 외에 다른 방법이 있습니까?


Answers

전역 변수를 코드에두고 memcpy ()를 사용하여 로컬 배열을 초기화하고 전역 배열의 내용을 로컬 배열에 복사합니다.


Stefaanv의 의견에 동의하지만, 이전에는 전 세계적이었던 경우 정적으로 설정하면 "쉬운 할당"을 얻을 수 있었고 마치 정적 정적 const 일 수 있습니다.

이러한 값이 가끔 변경되는 경우 재 컴파일을 피할 수 있도록 클래스를 만들 때 외부 파일에서 값을 읽는 것이 좋습니다.

또한 고정 배열 대신 std :: vector를 사용하여 일부 기능을 사용할 수도 있습니다.


내가 여기서 뭔가를 놓치고 있니? 아래 코드가 작동합니다. 간단히 멤버를 선언하고 바로 초기화하십시오.

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

귀하의 요구 사항이 정말로 허용한다면 다음 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}, ...
       {}
};

믹스에 다른 접근법을 하나 던지려면 (배열 데이터 멤버를 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())
{ }

당신은 그것을 정적으로 만들거나 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};

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

나는 이것이 오래된 게시물 인 것을 알고 있으며 이미 많은 훌륭한 답변들이 있습니다. 좀 더 완벽을 위해 AngularJS 사용하여 다른 것을 던질 것이라고 생각했습니다. 물론 이것은 Angular를 사용하는 경우에만 적용됩니다. 그럼에도 불구하고 어쨌든 그것을 넣고 싶습니다.

angular.forEach 는 두 개의 인수와 선택적 인 세 번째 인수를 취합니다. 첫 번째 인수는 반복 할 객체 (배열)이고 두 번째 인수는 반복 함수이며 선택적 세 번째 인수는 객체 컨텍스트입니다 (기본적으로 'this'로 루프 내에서 참조됩니다.).

각 회진 forEach 루프를 사용하는 여러 가지 방법이 있습니다. 가장 간단하고 아마도 가장 많이 사용되는 것은

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

한 배열에서 다른 배열로 항목을 복사하는 데 유용한 또 다른 방법은

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

그래도 할 필요는 없지만 다음과 같이하면됩니다. 앞의 예와 같습니다.

angular.forEach(temp, function(item) {
    temp2.push(item);
});

이제 angular.forEach내장 된 바닐라 맛의 for루프 에 반대 되는 기능 을 사용하는 것이 장단점이 있습니다 .

찬성

  • 쉬운 가독성
  • 간편한 쓰기 기능
  • 사용 가능한 경우 angular.forEachES5 forEach 루프를 사용합니다. 이제 각 for 루프는 for 루프보다 훨씬 느리기 때문에 cons 섹션에서 효율적으로 처리 할 것입니다. 일관되고 표준화 된 것이 좋기 때문에 이것을 프로로 언급합니다.

다음과 같은 두 개의 중첩 루프를 생각해보십시오. 정확히 같은 일을합니다. 우리가 2 개의 객체 배열을 가지고 있고 각 객체가 결과 배열을 포함한다고 가정 해 봅시다. 각각의 문자열은 Value 속성을 가지고 있습니다. 그리고 각각의 결과를 반복 할 필요가 있다고 가정 해 봅시다. 평등 한 경우 몇 가지 작업을 수행하십시오.

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

이것은 매우 단순한 가상의 예제이지만, 두 번째 접근법을 사용하여 루프에 3 중 임베디드를 작성 했으므로이 내용을 읽거나 쓰는 것이 매우 어려웠습니다.

단점

  • 능률. angular.forEach그리고 기본은 forEach, 그 문제에 관해서는, 모두 너무 느린 정상보다 for루프 .... 약 90 % 느린 . 따라서 대규모 데이터 세트의 경우 기본 for루프 를 유지하는 것이 가장 좋습니다 .
  • 휴식을 취하거나 계속하거나 지원을받지 마십시오. continue실제로 " accident "에 의해 지원됩니다 , angular.forEach당신 은 그 반복에 대한 함수에서 벗어나지 못하게하는 return;것과 같은 함수에 문장을 넣는 angular.forEach(array, function(item) { if (someConditionIsTrue) return; });것을 계속합니다. 이것은 네이티브 forEach가 중단을 지원하지 않거나 계속할 수도 없기 때문 입니다.

다른 여러 장단점이있을 것이라고 확신합니다. 여러분이 적합하다고 생각하는 것을 추가해 주시기 바랍니다. 나는 결론을 내릴 수 있습니다. 효율성이 필요하다면, for당신의 반복적 인 요구에 맞게 네이티브 루프를 고수 해야합니다. 그러나 데이터 집합이 더 작고 가독성과 쓰기 기능을 대신해서 포기하는 것이 좋을 경우, 그 angular.forEach나쁜 소년을 던지십시오 .







c++ arrays default-constructor