我有3D矢量课程
class Vector3D{
public: float x; float y; float z;
//some functions, e.g. operator+ - * /
//some 3D-specific function
};
和向量N-D类。
template<int constSize> class VecFloatFix{
float database[constSize];
//some functions, e.g. operator+ - * /
};
我注意到两个类之间存在代码重复,因此我认为我应该使
Vector3D
源自VecFloatFix<3>
:class Vector3D : public VecFloatFix<3>{
//some 3D-specific function
};
一切似乎都不错,只是直接有很多用户代码访问
Vector3D::x,y,z
。是否可以在不破坏用户代码的情况下从
Vector3D
派生VecFloatFix<3>
?我最好的猜测是:
template<int constSize> class VecFloatFix{
union{
float database[constSize];
float x,y,z; ????? sound like a hack
}
//some functions, e.g. operator+ - * /
};
编辑:将
x,y,z
硬编码为VecFloatFix
是不可持续的。如果我有一个从
Vector2D
派生的新类VecFloatFix<2>
,则Vector2D::z
可以正常编译(危险)。 最佳答案
这是一个仅公开大小为3的向量的x
,y
,z
分量的版本。显然,其他大小也可能是专门的。
template<int constSize> struct VecFloatStorage
{
float database[constSize];
};
template<> struct VecFloatStorage<3>
{
union
{
float database[3];
struct { float x, y, z; };
};
};
template<int constSize> class VecFloatFix : public VecFloatStorage<constSize>
{
public:
// Methods go here.
};
我不知道该标准是否保证
struct { float x, y, z; }
具有与float data[3]
相同的内存布局,但是实际上我可以肯定这一假设成立。GLM
库使用了类似的技巧,只是它们根本没有数组成员,而是提供了返回(&this->x)[idx]
的索引运算符。