将指针转换为int并返回到类型化对象

时间:2013-03-24 18:24:56

标签: c++ visual-c++ pointers casting

我需要一种简单的方法将指针转换为int,然后返回指针。我需要它作为可移植性的int,因为int在我的项目中比指针更容易随身携带。

启动播放器并返回指针:

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

使用指针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;

2 个答案:

答案 0 :(得分:9)

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

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

longunsigned long很可能足以容纳转换后的指针值而不会丢失信息;我从来没有在一个不是的系统上工作过。 (就个人而言,我倾向于选择无符号类型,但不是出于任何正当理由;要么两者都应该同样好用。)

所以你可以写,例如:

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

并使用unsigned longreinterpret_cast,SoundPlayer*>值转换回指针。

较新的实现提供了typedef uintptr_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()为您提供指针值,您将需要一个指针值。如果可能的话,只需将它作为指针。将其转换为整数意味着您必须决定使用哪种技术,并且必须跟踪整数值应该表示的指针类型。如果你犯了一个错误,要么使用一个不够大的整数类型,要么忘记你存储的指针类型,编译器可能不会警告你。

也许你有充分的理由需要这样做,但如果你能把指针存储为指针,那么你的生活就会轻松得多。

答案 1 :(得分:1)

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

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