2012-07-25 117 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;