2012-07-25 86 views
0

我对box2d很新颖,我试图使用b2body对象中的userdata(类型为void *)字段来存储int值(枚举值,所以我知道对象的类型)。C++和box2d:userdata将int转换为void *

我现在正在做的事情是:

int number = 1023; 

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

int rNumber = *(int*)data; 

,我得到正确的价值,但我一直在读围绕铸造到void *它不是便携或推荐...是我的代码跨平台?它是行为定义还是实施依赖?

谢谢!

+1

Windows API会一直这样做(甚至更糟糕)。如果没有其他方式存储它以备后用,没有多少选择,但是是一个空指针。你可以用适当的C++类型转换来完成,但是(第一个不投射,第二个投射为“static_cast”)。 – chris 2012-07-25 07:44:23

回答

2

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

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

由于语言标准没有说不同的指针必须具有相同的大小,或者以相同的方式工作,所以转换为任何其他类型都不是可移植的。只要void*必须足够宽以包含它们。

4

铸造到void *是便携式。不建议使用,因为您正在失去型号安全。任何东西都可以放入void *,任何事情都可以得到。它可以让你更容易地在脚下拍摄自己。否则void *是好的,只要你小心谨慎和谨慎。

1

void*的其中一个问题是,您需要知道(记录)它原来的类型才能正确投射。如果它最初是一个float,而你将其编译为一个int,编译器只会说出你的话。

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

编辑:你也应该用C++铸造风格而不是C即reinterpret_cast

+0

那些有什么区别? – 2012-07-25 07:57:25

1

无效*的习惯是某种过去(ISO C)的遗物,但非常方便。只要你小心地回转并转发你想要的类型,就可以安全地使用它。考虑像C++类系统或重载函数

反正你将有更好的转换操作符其他替代品,有时周围有没有其他的方法(void *的),另外一些时候,他们只是太方便了。

它可能会导致不可移植的代码,而不是因为铸造系统,而是因为一些人试图与他们进行非便携式操作。最大的问题在于(void *)与内存地址一样大,在很多平台中恰好也是平台整型的长度。

然而,在某些罕见的例外大小(无效*)!=大小(INT)

如果你试着做一些类型的操作/魔法与他们没有铸造回到你想要的类型,你可能有问题。你可能会惊讶的我多少次看到有人想要一个整数存储到一个void *指针

+0

他在Box2D中提到的void指针是为了方便使用框架的人。它允许您将Box2D世界中的对象返回到您引擎中您自己的对象之一。没有任何其他实际的方法来做到这一点没有void *。 – 2012-10-21 03:47:05

1

要回答你的问题,是的,这是安全的。

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

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

+0

我不认为这是公平的说userData是'for'以外的东西,而不是保存一些开发人员想要保留在那里的信息。 – Maxxx 2014-03-13 11:01:02