[英]C++ and box2d: userdata cast int to void*
我是box2d的新手,我正在尝试使用b2body对象中的userdata(类型为void *)字段存储一个int值(一个枚举值,所以我知道该对象的类型)。
现在我正在做这件事:
int number = 1023;
void* data = (void*)(&number);
int rNumber = *(int*)data;
并且我正确地获得了值,但是由于我一直在阅读将对象转换为void *,所以它不是可移植的,也不值得推荐...我的代码是跨平台的吗? 是行为定义的还是实现相关的?
谢谢!
强制转换为void *
是可移植的。 不建议这样做,因为您将失去类型安全性。 任何东西都可以放入一个void *
并且任何东西都可以取出。 这样可以更轻松地将自己拍到脚上。 否则,只要您格外小心谨慎, void *
就可以了。
实际上,您不是将int
强制转换为void*
,而是将int*
强制转换为void*
,这是完全不同的。
可以将指向任何类型的指针存储在void*
,然后将其再次投射回相同的类型。 保证可以正常工作。
强制转换为其他任何类型都不是可移植的,因为语言标准并不表示不同的指针必须具有相同的大小或工作方式。 只是void*
必须足够宽才能包含它们。
void*
的问题之一是,您需要知道(跟踪)它最初是什么类型的才能正确地进行转换。 如果它最初是一个float
而您将其转换为一个int
则编译器只会相信您的话。
为了避免这种情况,您可以为包含类型的数据创建包装器,这样就可以始终将其转换为正确的类型。
编辑:您还应该养成使用C ++转换样式而不是C的习惯,即reinterpret_cast
void *某种程度上是过去的遗物(ISO C),但非常方便。 您可以安全地使用它,只要小心地投射和转发所需的类型即可。 考虑其他替代方案,例如c ++类系统或重载函数
无论如何,您将拥有更好的强制转换运算符,有时没有其他方法可以避免(void *),有时则非常方便。
它可能导致非便携式代码,这不是因为强制转换系统,而是因为有些人很想对它们执行非便携式操作。 最大的问题在于(void *)与内存地址一样大,在许多平台中,它恰好也是平台整数的长度。
但是在一些罕见的例外中,size(void *)!= size(int)
如果您尝试对它们执行某种类型的操作/魔术而没有回退到所需的类型,则可能会遇到问题。 您可能会对我看到人们想要将整数存储到void *指针中的次数感到惊讶
要回答您的问题,是的,这样做很安全。
为了回答您没有提出的问题,void指针并不意味着将int保留在其中。Box2D具有该指针供您指向游戏引擎中的Entity对象,因此您可以在游戏中关联Entity物理仿真中的b2Body。 当一个b2Body与另一个实体交互时,它使您可以更轻松地对实体之间的交互进行编程。
因此,您不应该只是在该void *中添加枚举。 您应该将其直接指向该b2body表示的游戏对象,其中可能包含一个枚举。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.