我目前正在开发一款需要在3D引擎,物理引擎和脚本语言之间移动值的游戏“引擎”。由于我需要经常将物理引擎中的矢量应用到3D对象,并且希望能够通过脚本系统控制3D以及物理对象,我需要一种机制来转换一种类型的矢量(例如vector3d<float>
)到另一种类型的向量(例如btVector3
)。不幸的是,我不能对类/结构的布局做出任何假设,因此一个简单的reinterpret_cast
可能不会这样做。
所以问题是:是否有某种'静态'/非成员投射方法基本实现:
vector3d<float> operator vector3d<float>(btVector3 vector) {
// convert and return
}
btVector3 operator btVector3(vector3d<float> vector) {
// convert and return
}
现在这不会编译,因为转换运算符需要是成员方法。
(error C2801: 'operator foo' must be a non-static member
)
答案 0 :(得分:4)
我建议将它们写成一对自由函数(即不要担心它们是'运算符'):
vector3d<float> vector3dFromBt(const btVector3& src) {
// convert and return
}
btVector3 btVectorFrom3d(const vector3d<float>& src) {
// convert and return
}
void f(void)
{
vector3d<float> one;
// ...populate...
btVector3 two(btVectorFrom3d(one));
// ...
vector3d<float> three(vector3dFromBt(two));
}
答案 1 :(得分:3)
您还可以使用模板化的包装类,如:
template<class V>
class vector_cast {};
template<>
class vector_cast<vector3d> {
const vector3d& v;
public:
vector_cast(const vector3d& v) : v(v) {};
operator vector3d () const {
return vector3d(v);
}
operator btVector3 () const {
// convert and return
}
};
template<>
class vector_cast<btVector3> {
const btVector3& v;
public:
vector_cast(const btVector3& v) : v(v) {};
operator btVector3 () const {
return btVector3(v);
}
operator vector3d () const {
// convert and return
}
};
用法:
void set_origin(btVector3 v);
// in your code:
vector3d v;
// do some fancy computations
set_origin(vector_cast(v));
// --- OR the other way round --- //
void set_velocity(vector3d v);
// in your code:
btVector3 v;
// do some other computations
set_velocity(vector_cast(v));
答案 2 :(得分:1)
您在问题中的陈述是正确的。类型转换运算符需要是非静态成员。如果您真的想要转换类型语义,可以扩展每个类以便在应用程序代码中使用:
// header:
class ConvertibleVector3d;
ConvertibleBtVector : public btVector3
{
operator ConvertibleVector3d() const;
}
ConvertibleVector3d : public vector3d<float>
{
operator ConvertibleBtVector() const;
}
//impl:
ConvertibleBtVector::operator ConvertibleVector3d() const
{
ConvertibleVector3d retVal;
// convert this into retVal...
return retVal;
}
ConvertibleVector3d::operator ConvertibleBtVector() const;
{
ConvertibleBtVector retVal;
// convert this into retVal...
return retVal;
}
void f(void)
{
ConvertibleVector3d one;
// ...populate...
ConvertibleBtVector two(one);
// ...
ConvertibleVector3d three;
three = two;
}
这些名字有点冗长,但希望意图明确。
公共继承意味着您应该能够以与基类相同的方式使用这些类的实例,除非它们可以相互分配和构造。当然这将两个类联系在一起,但这可能是可以接受的,因为它听起来就像你的应用程序打算做的那样。