2012-07-25 113 views
5

我正在製作一個涉及三維座標的庫,並發現三維角度的組件有兩個名稱:偏航俯仰滾動和航向滾動,海拔銀行類參考成員指向同一類中的其他成員

所以,我提出以下(在C++ 11完成):

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) 
} 

其中有保持兩個名稱方案之間的符號等價的利益。例如:

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

我在想,如果編譯器會找出引用是不必要的,或者它是否會保持指針的結構。

另外,有沒有更好的方法來爲一個成員有兩個名字?

回答

2

我在想,如果編譯器會找出引用是不必要的,或者它是否會保持指針的結構。

在99.9%的情況下,指針將保留在結構中。我沒有看到編譯器通過翻譯單元排除它們的方法。因爲你的語法是無效的,所以你必須在構造函數中初始化引用,這很可能被隱藏起來。所以沒有辦法讓它知道哪個參考引用哪個成員。

也可能會有一些性能開銷。例如:

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

爲什麼要創造如此多的公共變量?

您只需做一些getter和setter方法(僞):

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 2012-07-25 13:58:08

+0

@betabandido編輯我的代碼走^ _ ^,我說這是'pseudocode'。顯然,它不會完全像這樣的^ _ ^(我做的BTW返回引用:-P) – Neal 2012-07-25 13:59:29

+0

@LuchianGrigore啊啊啊! **僞代碼** ___pseudocode___ _pseudocode_。 – Neal 2012-07-25 14:36:31

1

我可以想到兩個不同的選項。第一個是幾乎什麼@Neal已經提出,但其中真正的C++代碼:

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; 

當你有一個經常提及一個角度,你只是想在struct讀取值的第二組使用。例如:

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

我檢查了GCC生成的彙編代碼。直接使用struct屬性(例如,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;