2010-01-03 3 views
3

C++ 코드에서 C 구조를 초기화하는 더 좋은 방법이 있습니까?C++ 코드에서 C 구조 초기화

변수 선언 지점에서 초기화 프로그램 목록을 사용할 수 있습니다. 그러나 이것은 모든 인수가 컴파일 타임에 알려지지 않았거나 로컬/전역 인스턴스를 선언하지 않은 경우 유용하지 않습니다. 예 :

구조체를 선언하고 API를 사용하는 레거시 C 코드 지역의 인스턴스를 생성 한 후 시간 (myStruct.x = 5; 등)에 각 멤버를 설정 C 라이브러리

void doSomething(std::vector<MyStruct> &items) 
{ 
    items.push_back(MyStruct(5,rand()%100,items.size()));//doesn't work because there is no such constructor 
    items.push_back({5,rand()%100,items.size()});//not allowed either 

    //works, but much more to write... 
    MyStruct v; 
    v.x = 5; 
    v.y = rand()%100; 
    v.z = items.size(); 
    items.push_back(v); 
} 

를 사용하여이

typedef struct 
{ 
    int x, y, z; 
} MyStruct; 

C++ 코드를 시도 할 때 읽기 다소 어려운 진짜 고통이며, 컨테이너에 20 개의 다른 항목을 추가하십시오 ...

+3

C 또는 C++ 솔루션을 찾으십니까? – Christoph

답변

7

당신이 (C++ 03에서 최선의 해결책이다하지만 당신은 아마 C와의 호환성에 제약 조건이) 생성자를 추가 할 수없는 경우,

MyStruct makeAMyStruct(int x, int y, int z) 
{ 
    MyStruct result = { x, y, z }; 
    return result; 
} 

items.push_back(makeAMyStruct(5,rand()%100,items.size())); 

편집 : 나는 C++ 0X이 정확한 문제에 대한 뭔가를 제공하는 지금 확인 한 것 :

items.push_back(MyStruct{5,rand()%100,items.size()}); 

g에서 사용할 ++ 4.4 동일한 효과 기능을 쓸 수 있습니다 .

+0

+1 : 그는 그가 찾고있는 대답이라고 생각합니다 – Christoph

+0

btw : 왜 초기화 목록을 사용하지 않습니까? – Christoph

+0

정당한 이유가 있지만, 제 기능을 바꿀 것입니다. – AProgrammer

7

C99 복합 리터럴을 찾고 있습니다. 예제 코드 :

struct foo *foo = malloc(sizeof *foo); 
*foo = (struct foo){ bar, baz }; 
+0

컴파일러 (VC++ 9)에 의해 지원 되었다면 훌륭한 해결책이 될 것입니다. ( –

+2

이번에는 복합 리터럴이 C++에서 지원하지 않는 C99 기능이므로 실제로 컴파일러의 잘못이 아니며 질문을 잘못 읽고 생각했습니다. C에서 해결책을 찾고 있었어요 ... – Christoph

+0

일부 설명 및 C++ 0x http://stackoverflow.com/questions/1705147/struct-initialization-of-the-cc-programming-language/1705166#1705166을 참조하십시오. 구문 – Christoph

3

에 대해 어떻게 :

MyStruct v = {5, rand()%100, items.size()}; 
items.push_back(v); 
+0

여러 가지 일을하기 위해 v1, v2, v3, v4 등을 수행해야합니다. 로컬을 재사용 할 방법이 없습니까? –

+0

v1, v2, v3 및 v4를 사용하는 경우 동일한 값을 갖기를 원하지 않는 한 4 회 이상 쓸 수 있습니다.이 경우 단순한 할당을 할 수 있습니다. v [0], v [1], v [2], v [3] 및 v [4]가 있으면 대신 루프를 사용할 수 있습니다. –

+0

나는 이것에 대해 100 % 확실하지는 않지만, 나는 생각한다 : MyStruct vs [2] = {{1, 2, 3}, {2, 3, 4}}; – James

2

당신이 요구하는 것을 취소하지 않습니다. C++에서 확실한 해결책이 구조체를 생성자 제공하는 것입니다 :

struct MyStruct { 
    int x, y, z; 
    MyStruct(int ax, int ay, int az) : x(ax), y(ay), z(az) {} 
}; 
+0

그가 C의 솔루션을 찾고있다 – Christoph

+0

그것은 – James

+0

태그가 C++입니다. 그렇다면 왜 그가 C++로 태그를 추가 했습니까? 이것이 제가 분명하지 않다고 말한 이유입니다. –

2

C++ 생성자와 비슷한 함수를 생성하여 초기화하십시오.

+0

(+1) KISS는 모든 관점에서 대답합니다. –

1

또 다른 옵션은 구조체에서 파생되어 거기에 생성자를 추가하는 것입니다.

struct MyDerivedStruct : public MyStruct 
{ 
    MyDerivedStruct(int xi, int yi, int zi) 
    { 
     x = xi; 
     y = yi; 
     z = zi; 
    } 
} 

그런 다음이 파생 형식을 자신의 코드에 사용하고 필요할 때 C 라이브러리에 전달할 수 있습니다. 적절한 경우 언어는 암시 적으로 MyStruct으로 변환해야합니다.

보너스로 다른 유용한 멤버 함수를 추가 할 수도 있습니다.이 함수는이 유형을 사용하는 많은 레거시 C 함수를 래핑하는 경우도 있습니다.