使矢量 3D 源自矢量 ND,需要保留场 x y z
make vector 3D derived from vector ND, need to retain field x y z
我有一个矢量 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+ - * /
};
我注意到两个类之间存在代码重复,所以我认为我应该从VecFloatFix<3>
派生Vector3D
:-
class Vector3D : public VecFloatFix<3>{
//some 3D-specific function
};
一切似乎都很好,除了有很多用户代码直接访问Vector3D::x,y,z
。
是否可以在不破坏用户代码的情况下从VecFloatFix<3>
派生Vector3D
?
我最好的猜测是:-
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
是不可持续的。
如果我有一个派生自VecFloatFix<2>
的新类Vector2D
,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]
的索引运算符。
这绝不保证有效,因为它使用实现定义和可能未定义的行为。不过,明智的实现可能会按预期运行。
template<int constSize>
class VecFloatFix{
public:
union {
float database[constSize];
struct {
int x, y, z;
};
};
};
这也database
公开。看不到解决这个问题的方法,但没什么大不了的,因为无论如何你都提供了operator[]
。
这假设constSize >= 3
.如果您需要更小的尺寸,这可以通过更多的黑客来实现。所有向量都将具有x
y
和z
成员,但只有 3D 及以上版本才能将它们全部使用。2D 矢量将只有 x
且y
可用(任何z
的使用都可能导致错误(,而 1D 矢量将只有 x
.注意 我拒绝对以下任何一项负责。
template<int constSize>
class VecFloatFix{
public:
union {
float database[constSize];
struct {
float x;
};
struct {
spacer<constSize, 1> sp1;
typename spacer<constSize, 1>::type y;
};
struct {
spacer<constSize, 2> sp2;
typename spacer<constSize, 2>::type z;
};
};
};
其中spacer
是这样定义的:
template <int N, int M, bool enable>
struct filler;
template <int N, int M>
struct filler<N, M, true>
{
float _f[M];
typedef float type;
};
template <int N, int M>
struct filler<N, M, false>
{
struct nothing {};
typedef nothing type;
};
template <int N, int M>
struct spacer
{
filler<N, M, (N>M)> _f;
typedef typename filler<N, M, (N>M)>::type type;
};
试驾:
VecFloatFix<4> vec4;
VecFloatFix<3> vec3;
VecFloatFix<2> vec2;
VecFloatFix<1> vec1;
`smoke test`
vec3.database[0] = 42;
vec2.database[1] = 99;
std::cout << vec3.x << std::endl;
std::cout << vec2.y << std::endl;
// make sure `y` aliases `database[1]`
std::cout << & vec2.y << std::endl;
std::cout << & vec2.database[1] << std::endl;
// make sure sizes are as expected
std::cout << sizeof(vec4) << " " << sizeof (vec3) << " " << sizeof(vec2) << " " << sizeof(vec1) << std::endl;
- 有根的二进制搜索树.保留与其父级的链接
- 无法将结构注册为增强几何体3D点
- 为多个会话保留XPtr
- OpenGL大的3D纹理(>2GB)非常慢
- 保留对其他类的成员函数的引用
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- 指针保留字符串
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 如何让 GCC/Clang 在保留标识符上出错
- 必须为 C++20 协程帧保留多少内存?
- 如何将一个窗口保留在另一个应用程序窗口的前面
- 使用 char 分隔符解析C++中的字符串,但将可重复的字符保留为每个解析的子字符串 (C++ STL) 中的分隔符
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- 局部变量保留函数中的值
- 保留函数指针模板参数
- 使矢量 3D 源自矢量 ND,需要保留场 x y z
- 尝试创建一个 3D 矢量,该矢量将保留指向指向无符号字符的指针的指针
- C++ 3D 矢量保留"blocks"