C ++:使用一种类型作为另一种类型

时间:2010-11-19 21:27:08

标签: c++ class types

我正在为我的C ++项目使用Chipmunk物理引擎。

Chipmunk拥有它自己的矢量cpVect,它只不过是struct { double x, y; };

但是我的项目中有自己的运算符重载Vector类 - 我想将它作为cpVect使用,反之亦然,没有任何转换 (我class Vector的唯一数据字段也是double x, y

目前我将它用于隐式转换(用于参数传递,将Vector变量设置为cpVect等)。

inline operator cpVect() { return cpv( x, y ); };
inline Vector( cpVect v ) : x( v.x ), y( v.y ) {}

这适用于大多数事情,但有一些问题 - 例如,它与使用带有cpVect数组的Vector类型的数组不兼容。

为此,我目前必须这样做:

Vector arrayA[123];
cpVect* arrayB = (cpVect*) arrayA;
  • 是否可以通过某种方式将我的Vector用作cpVect,反之亦然?数据与两种结构都相同,我的只有其他方法。

3 个答案:

答案 0 :(得分:2)

所以,如果我理解你,你就有这个:

class Foo
{
  double x, y;
};

class Bar
{
  double x, y;
};

...你想要假装Foo实际上是Bar,对吧?

你不能 - 不能没有唤起Undefined Behavior。无论你尝试什么,你都会陷入巨大的UB黑洞。

  • 如果您尝试使用工会,则在分配到my_union.foo并从my_union.bar读取
  • 时,您会唤起UB
  • 如果你尝试reinterpret_cast,你会在尝试使用铸造指针时唤起UB
  • 如果您尝试使用C风格的演员表,您将遇到与上述相同的问题

问题是:即使FooBar 看起来相同,它们也不一样。就C ++而言,它们是完全不同的类型,彼此完全无关。这是一件好事,但它也可能会产生一些看似人为和随意的障碍。

因此,为了在不唤起UB的情况下执行此操作,您需要转换。你可以通过简单地向Bar添加一些设施来使这几乎自动化(我认为这是你写的那个,而不是库中的那个):

class Bar
{
public:
  Bar(const Foo& foo) : x(foo.x), y(foo.y) {}; // lets you convert from Foo to Bar
  Bar& operator=(const Foo& foo) { x = foo.x; y = foo.y; return * this; }

  operator Foo() const { Foo ret;  ret.x = x; ret.y = y; return ret; } // lets you convert ffrom Bar to Foo
private: 
  double x, y;
};

这将允许您从Foo转到Bar,然后在很少或没有代码的情况下再次返回。此外,编译器将在发布版本中优化大量此类功能。

答案 1 :(得分:0)

如果这两个都是简单的POD(没有虚拟功能等),那么一个简单的reinterpret_cast可以在这里保存。

答案 2 :(得分:0)

从他们那里获取并修复问题?似乎很简单,有1000个陷阱。 :)