2011-04-18 137 views
0
漂浮

这是有效/便携/法人代码:访问非数组通过指针

class Vector3 
{ 
public: 

    float& operator [] (const size_t i) 
    { 
    assert(i < 3); 

    return *(&x+i); 
    } 

    float x, y, z; 
}; 

已经有相当这里我想用[]操作,最终把数组中的元素的几个实例(以避免如果/切换语句)。我从来没有做过这种特定方法正在做的事情。我可以告诉它为什么会起作用(x,y和z是连续的),但它是否好(或至少可以)练习?

此外,代码是否需要#pragma pack 1以保证无垫片包装,或者没有它可以工作吗?我之所以问是因为段实际上是从OGRE3D矢量类采取和我没有看到任何地方#pragma pack 1

回答

4

号这是不正确的,是不是好的做法。这是可能这三个元素之间不会有填充(即使没有指示编译器打包结构),因此很可能您可以像访问数组元素一样访问成员。但是,这并不能使代码正确:写入的代码会产生未定义的行为。

正确的做法是使用组件的访问函数,

struct Vector 
{ 
    float& operator[](std::size_t i)  { return data_[i]; } 
    float operator[](std::size_t i) const { return data_[i]; } 

    float& x() { return data_[0]; }  
    float& y() { return data_[1]; }  
    float& z() { return data_[2]; } 

    float x() const { return data_[0]; } 
    float y() const { return data_[1]; } 
    float z() const { return data_[2]; } 

private: 
    float data_[3]; 
}; 
0

我相信它的实际工作,因为C++编译器不允许一个访问限定符内重新排序类/结构的成员 - 让他们总是要奠定了X,Y,Z。这是为了向后兼容C,其中编译器不允许重新排序成员。

但是:我认为这对于自己的利益来说有点太聪明。一对夫妇IFS的或运营商内部的开关似乎吸尘器我,但我想这是可能的,他们认为这是性能关键,如果它是一个食人魔载体,这样也许可以解释为什么它完成这种方式。

我不认为会需要包装杂注,因为所有三个成员都是相同的大小,所以你会期望他们相互毗邻。尽管如此,我并不是100%肯定的。

0

将结构元素对齐到64位边界的64位机器会失败,如果代码假定32位浮点数是连续的,则可能不会发出警告。

只是因为它适用于所有32位和16位架构中,我知道所有实现大约不会使它通常是有用的。充其量,这是一个适用于多种实现的特殊情况。据推测,未来将带来128位和256位体系结构,它可能会失败,就像奇怪。

这种隐藏的假设毫无必要地制造痛苦和折磨那些谁继承了这样的代码,甚至你,如果你忘记它。它有这样一个可疑的表达,它真的很难理解任何微薄的利益被证明是一种交易的利益。请了解KISS principle。知道。活着吧。爱它。