我对box2d很新,我正在尝试使用b2body对象中的userdata(类型为void *)字段来存储int值(枚举值,所以我知道对象的类型)。
现在我正在做这件事:
int number = 1023;
void* data = (void*)(&number);
int rNumber = *(int*)data;
并且我正确地得到了价值,但是因为我一直在阅读铸造无效*它不可移植或推荐......我的代码跨平台?它的行为是定义的还是依赖于实现的?
谢谢!
答案 0 :(得分:4)
转换为void *
是可移植的。不推荐使用,因为您正在失去类型安全性。任何东西都可以放入void *
,任何事情都可以解决。它可以让你更容易在脚下射击。否则void *
只要你小心谨慎就行了。
答案 1 :(得分:2)
您实际上并没有将int
投射到void*
,而是将int*
投射到void*
,这完全不同。
指向任何类型的指针都可以存储在void*
中,然后再次转换回相同的类型。这是有效的。
转换为任何其他类型都不可移植,因为语言标准并未说明不同的指针必须具有相同的大小,或者以相同的方式工作。只是void*
必须宽到足以包含它们。
答案 2 :(得分:1)
void*
的一个问题是你需要知道(跟踪)它最初的类型才能正确地进行转换。如果它原来是float
并且你把它归结为int
,编译器就会接受你的话。
为避免这种情况,您可以为包含该类型的数据创建一个包装器,这样您就可以始终将其转换为正确的类型。
编辑:您还应养成使用C ++投射风格而不是C的习惯,即reinterpret_cast
答案 3 :(得分:1)
void *在某种程度上是过去的遗物(ISO C),但非常方便。您可以安全地使用它,只要您小心地向前和向后转换您想要的类型。考虑其他替代方案,如c ++类系统或重载函数
无论如何你会有更好的强制转换操作符,有时候没有别的办法(void *),有些时候它们太方便了。
它可能导致不可移植的代码,不是因为转换系统,而是因为有些人很想用它们进行非便携式操作。最大的问题在于(void *)与内存地址一样大,在许多平台中恰好也是平台整数的长度。
然而,在一些罕见的例外中,size(void *)!= size(int)
如果你尝试使用它们进行某种类型的操作/魔术而不回滚到你想要的类型,你可能会遇到问题。您可能会惊讶于我看到有多少人希望将整数存储到void *指针
中答案 4 :(得分:1)
要回答你的问题,是的,这样做是安全的。
要回答你没有问过的问题,那个void指针并不意味着保持一个int.Box2D有指针让你指向游戏引擎中的Entity对象,这样你就可以关联一个实体在你的游戏中物理模拟中的b2Body。当一个b2Body与另一个b2Body交互时,它允许您更轻松地对您的实体进行相互交互编程。
所以你不应该只是在那个虚空中加入一个枚举*。你应该将它直接指向那个b2body代表的游戏对象,它可能有一个枚举。