2012-07-25 3 views
5

3 차원 좌표가 포함 된 라이브러리를 만들고 3 차원 각도의 구성 요소 이름에 yaw-pitch-roll과 heading- 두 이름 체계 사이의 표기법과 동등한를 유지하는 장점이클래스 참조 멤버가 같은 클래스의 다른 멤버를 가리키고 있음

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 
    float &yaw = heading; 
    float &pitch = elevation; 
    float &roll = bank; 

    // Some Constructors (copy and assignment have to be made manually) 
} 

: 고도-은행은

그래서 나는 다음 (11 C++에서 수행)했다. 예를 들어 컴파일러가 참조가 필요했다 알아낼 것입니다 경우, 또는이 구조에서 포인터를 유지한다면

Angle angle; 
rotate(angle.yaw); // this is equivalent to rotate(angle.heading) 

궁금 해서요.

또한 한 회원에게는 두 개의 이름을 사용하는 것이 더 좋은 방법입니까?

답변

2

컴파일러가 참조가 필요했다 알아낼 것입니다 경우, 또는 구조에 대한 포인터를 유지한다면 :

당신은 그냥 getter 및 setter (의사)를 만들 수 있습니다.

경우의 99.9 %에서 포인터가 구조에 보관됩니다. 나는 컴파일러가 번역 단위에 대해 그들을 제외시키는 방법을 보지 못했다. 귀하의 구문이 유효하지 않기 때문에 Esp는 매우 잘 숨겨져있는 생성자에서 참조를 초기화해야합니다. 따라서 어떤 참조가 어떤 멤버를 참조 하는지를 알 수있는 방법이 없습니다.

성능 오버 헤드가있을 수 있습니다. 예 :

float x = a.elevation; 
013F13E0 fld   dword ptr [ebp-18h] 
013F13E3 fstp  dword ptr [x] 
    float y = a.pitch; 
013F13E6 mov   eax,dword ptr [ebp-0Ch] 
013F13E9 fld   dword ptr [eax] 
013F13EB fstp  dword ptr [y] 

실제로 내부적으로 참조는 포인터처럼 작동합니다. 따라서 여분의 mov은 해당 포인터의 역 참조를 보충합니다.

나는 그 스타일에 대해 걱정할 필요가 없다. 걱정하지 않겠다. 그리고 같은 일을하는 두 명의 회원을두고있는 것은 ... 잘못된 것 같습니다.

0

왜 많은 공용 변수를 만드나요? 궁금

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 

    float& yaw() const { 
     return heading; 
    } 
    float& pitch() const { 
     return elevation; 
    } 
    float& roll() const { 
     return bank; 
    } 

    //etc... 

    // Some Constructors (copy and assignment have to be made manually) 
} 
+0

기본적으로 나는 똑같은 것을 쓰고있었습니다 :) 그러나 실제 속성에 대한 참조를 반환해서는 안됩니까? 그렇지 않으면 대체 이름을 통해 수정할 수 없습니다. 사실,'const float & yaw() const;'와'float & yaw();'두 가지 메소드가 제공되어야한다. 그런 다음 상수'각도 '에 대한 참조로도 작동합니다. – betabandido

+0

@betabandido 편집 내 코드 away^_^그것이'pseudocode'라고 말한 것입니다. 분명히 이것은^_ ^과 완전히 같지 않을 것입니다. (그리고 저는 참고 문헌 btw : -P를 반환합니다) – Neal

+0

@LuchianGrigore ahhh! ** 의사 코드 ** ___ 의사 코드 __ _ 의사 코드. – Neal

1

두 가지 옵션을 생각해 볼 수 있습니다. 첫 번째는 실제 C++ 코드를 포함 @Neal 이미 제안 것을 꽤 많은 수 있지만 다음과 같습니다

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 

    float& yaw() { return heading; } 
    float& pitch() { return elevation; } 
    float& roll() { return bank; } 

    const float& yaw() const { return heading; } 
    const float& pitch() const { return elevation; } 
    const float& roll() const { return bank; } 
}; 

방법의 첫 번째 세트는 const가 아닌 참조를 반환, 그래서 실제로 이러한 통해 구조체의 특성을 수정할 수 있습니다 행동 양식. 예를 들어 :

당신이 각도에 일정한 기준이 있고 단지 구조체의 값을 읽고 자하는 경우 두 번째 세트를 사용
Angle a{60, 45, 0}; 
a.roll() = 15; 

. 예 :

void print_yaw(const Angle& a) { 
    std::cout << "yaw=" << a.yaw() << std::endl; 
} 

GCC에서 생성 한 어셈블리 코드를 확인했습니다. 구조체 속성 (예 : a.heading)을 직접 사용하고 별칭 메소드 (예 : a.yaw())를 사용하면 동일한 어셈블리 코드가 생성되므로 별칭 메소드를 사용하면 어떠한 불이익도 치룰 수 없습니다.

내가 생각할 수있는 두 번째 방법은 전혀 다른 접근 방식을 사용하는 것입니다. 이런 식으로 :

enum Accessors { HEADING=0, ELEVATION, BANK }; 
enum AliasedAccessors { YAW=0, PITCH, ROLL }; 
typedef float Angle[3]; 

Angle a{60, 45, 0}; 
std::cout << a[HEADING] << " must be equal to " << a[YAW] << std::endl; 
관련 문제