C++和box2d:userdata将int强制转换为void*
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++类系统或重载函数
无论如何,你会有更好的cast运算符,有些时候没有其他方法(void*),有些时候它们太方便了。
它可能导致不可移植的代码,这不是因为强制转换系统,而是因为有些人很想用它们进行不可移植操作。最大的问题在于(void*)是一个与内存地址一样大的地址,在许多平台中,它恰好也是平台整数的长度。
然而,在一些罕见的例外情况下,size(void*)!=大小(int)
如果你试图用它们进行某种类型的操作/魔术,而不返回到你想要的类型,你可能会遇到问题。你可能会惊讶于我见过多少次有人想把一个整数存储到一个空*指针中
要回答您的问题,是的,这样做是安全的。
为了回答你没有问的问题,这个void指针并不意味着要保留int。Box2D有一个指针可以让你指向游戏引擎中的Entity对象,这样你就可以将游戏中的实体与物理模拟中的b2Body关联起来。当一个b2Body与另一个b2Body交互时,它允许您更容易地对实体之间的交互进行编程。
所以你不应该只是把一个枚举放在这个空白中。您应该将其直接指向由该b2body表示的游戏对象,该对象中可能有一个枚举。
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 将尾部调用void(i32,..)位转换为llvm::函数以获取FnAttribute
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- Boost buffer_cast 无法从 void* 转换为 PointerToPodType
- 将通用引用强制转换为可调用的 void 指针,反之亦然
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 在不同的编译器上转换为 void**
- 当我使用 void 函数的返回值(通过强制转换函数指针)时,究竟会发生什么?
- 不能在 if 语句 - c++ 中使用 void func 直接将字符串转换为大写
- 是否可以将已经初始化的变量转换为 void*?
- 错误:从'void*'到'const uint8_t* {aka const unsigned char*}'的转换无效 [-允许]
- 将可变参数模板类型转换为 void,预期')'之前
- 如何在运行时将指向派生类的 void* 正确转换为指向基类的 void*
- 是否强制转换void**并将第一个字节设置为nullptr
- 如何转换 void* 以访问结构的静态数据成员?
- 警告传递"double"以转换"void moveto(int, int)"的 2
- 是否有一种方法可以自动转换void指针的类型
- 在构造函数中强制转换void*并访问值
- 重新解释不带类型标识符的强制转换void
- 强制转换void指针