0

我对box2d很陌生,我正在尝试使用b2body对象中的userdata(void *类型)字段来存储一个int值(一个枚举值,所以我知道对象的类型)。

现在我正在做这样的事情:

int number = 1023;

void* data = (void*)(&number);

int rNumber = *(int*)data;

我得到了正确的值,但是正如我一直在阅读关于强制转换为 void* 它不可移植或不可推荐的......我的代码是跨平台的吗?它的行为是定义的还是依赖于实现的?

谢谢!

4

5 回答 5

4

Casting tovoid *是可移植的。不建议这样做,因为您正在失去类型安全性。任何东西都可以放入a void *,任何东西都可以取出。它使你更容易在脚上射击自己。否则void *,只要您小心谨慎并格外小心,就可以了。

于 2012-07-25T07:45:27.577 回答
2

你实际上不是投射intvoid*,你投射int*void*,这是完全不同的。

指向任何类型的指针都可以存储在 a 中void*,并且可以再次转换回相同的类型。这是保证工作。

转换为任何其他类型都是不可移植的,因为语言标准没有规定不同的指针必须具有相同的大小或以相同的方式工作。只是它void*必须足够宽以容纳它们。

于 2012-07-25T08:04:51.193 回答
1

问题之一void*是您需要知道(跟踪)它最初是什么类型才能正确转换它。如果它最初是 afloat并且你将它放在一个int编译器上,编译器就会相信你的话。

为避免这种情况,您可以为包含该类型的数据创建一个包装器,这样您就可以始终将其转换为正确的类型。

编辑:您还应该养成使用 C++ 铸造风格而不是 C 即的习惯reinterpret_cast

于 2012-07-25T07:47:49.350 回答
1

void * 在某种程度上是过去的遗物(ISO C),但非常方便。只要您小心地向后和向前转换您想要的类型,您就可以安全地使用它。考虑其他替代方案,例如 c++ 类系统或重载函数

无论如何,您将拥有更好的演员阵容,有时没有其他办法(void *),有时他们太方便了。

它可能导致代码不可移植,不是因为强制转换系统,而是因为有些人很想用它们进行不可移植的操作。最大的问题在于 (void*) 与内存地址一样大,在许多平台中恰好也是平台整数的长度。

但是在一些罕见的例外情况下 size(void*) != size(int)

如果您尝试对它们进行某种类型的操作/魔术而不转换回您想要的类型,您可能会遇到问题。您可能会惊讶于我看到有多少人想将整数存储到 void* 指针中

于 2012-07-25T07:57:47.630 回答
1

要回答您的问题,是的,这样做是安全的。

要回答你没有问的问题,那个 void 指针并不是用来保存 int 的。Box2D 有这个指针让你指向游戏引擎中的 Entity 对象,所以你可以在你的游戏中关联一个 Entity到物理模拟中的 b2Body。当一个 b2Body 与另一个 b2Body 交互时,它允许您更轻松地对实体进行编程。

所以你不应该只是在那个 void* 中放一个枚举。您应该将它直接指向由该 b2body 表示的游戏对象,其中可能有一个枚举。

于 2012-10-21T03:57:11.773 回答