2

I need a simple way to convert a pointer to an int, and then back to the pointer. I need it as an int for portability, since an int is easier to carry around in my project than a pointer.

Start player and return pointer:

SoundPlayer* player = new FxPlayerTiny();
return (int)player; // this works, but is it correct?

Stop player using pointer int:

FxPlayerTiny* player = static_cast<FxPlayerTiny*>((int*)num); // this gives me an error
FxPlayerTiny* player = (FxPlayerTiny*)((int*)obj); // this works, but is it correct?
delete player;
4

2 回答 2

9

最好的办法是修复您的项目,以便它可以处理指针。整数和指针是两个不同的东西。您可以来回转换,但如果您不小心,此类转换可能会丢失信息。

int根据实现和底层平台,来回转换指针值很容易丢失信息。例如,有系统上int的指针小于指针。如果您有 32 位ints 和 64 位指针,那么将指针转换为 anint并再次返回几乎肯定会给您一个无效的指针。

很可能longunsigned long足够宽以保存转换后的指针值而不会丢失信息;我从来没有在一个没有它的系统上工作过。(就个人而言,我更喜欢无符号类型,但不是出于任何真正好的理由;两者都应该同样有效。)

所以你可以写,例如:

SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<unsigned long>player;

unsigned long使用 . 将值转换回指针reinterpret_cast,SoundPlayer*>

较新的实现提供 typedefuintptr_tintptr_t,它们是无符号和有符号整数类型,保证在往返指针到整数到指针的转换中正常工作。它们是在 C99 中引入的,并且可以<stdint.h>标题中定义。(指针大于任何整数类型的实现不会定义它们,但这种实现很少见。)C++ 在 2011 标准中采用它们,在<cstdint>标头中定义它们。但 Microsoft Visual C++ 从 2010 版本开始支持它们。

此保证仅适用于普通指针,不适用于函数指针或成员指针。

所以如果你必须这样做,你可以写:

#include <cstdint>
SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<std::uintptr_t>player;

但首先,请考虑这一点。new FxPlayerTiny()给你一个指针值,你会想要一个指针值。如果可能,请将其保留为指针。将其转换为整数意味着您必须决定使用几种技术中的哪一种,并且您必须跟踪整数值应该表示的指针类型。如果你犯了一个错误,要么使用了一个不够大的整数类型,要么忘记了你存储的指针类型,编译器可能不会警告你。

也许您有充分的理由需要这样做,但是如果您可以将指针存储为指针,您的生活将会轻松得多。

于 2013-03-24T22:20:11.067 回答
1

不建议使用 int 来实现可移植性,尤其是因为sizeof (int)sizeof (void*)可能会有所不同(例如在为 Windows x64 编译时)。如果用户界面需要整数,最好使用指针表并通过索引访问它们。

但是,如果要将指针转换为整数,反之亦然,那么简单的转换就足够了,但它是一样的,如果sizeof *int) == sizeof (void*).

于 2013-03-24T18:41:44.507 回答