我在Quake 3的渲染库中找到了这个代码。有这个函数:
void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap );`
它在一个循环中被调用,除此之外的其他东西:
R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex, qfalse );
奇怪的部分是poly被声明为srfPoly_t *poly
。到底是怎么回事
这里?它将srfPoly_t
对象转换为(void *)
,然后输入
作为surfaceType_t
对象运行。
以下是相关结构的声明:
typedef enum {
SF_BAD,
SF_SKIP, // ignore
SF_FACE,
SF_GRID,
SF_TRIANGLES,
SF_POLY,
SF_MD3,
SF_MD4,
SF_FLARE,
SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity
SF_DISPLAY_LIST,
SF_NUM_SURFACE_TYPES,
SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int )
} surfaceType_t;
typedef struct srfPoly_s {
surfaceType_t surfaceType;
qhandle_t hShader;
int fogIndex;
int numVerts;
polyVert_t *verts;
} srfPoly_t;
这是在C中工作,但我试图在C ++中实现类似的东西, 但我收到以下错误:
Error 1 error C2664: 'int RefDef::AddDrawSurf(surfaceType_t *)' : cannot convert argument 1 from 'void *' to 'surfaceType_t *'
看来我无法在C ++中执行这种类型的强制转换,或者可能存在 其他我无法理解的东西。我不太熟悉C ++和 我很想知道如何使用它来设置类似的东西。
我假设这与C ++中的类型检查有关,所以事实并非如此 允许。如何以安全的方式在C ++中实现类似的东西?
答案 0 :(得分:5)
这适用于C,因为结构只是内存块,结构中的每个元素都是连续布局的。此转换是有效的,因为n
结构的第一个srfPoly_t
字节由该结构中的surfaceType_t
枚举组成。被调用函数尝试将传入的srfPoly_t
解释为surfaceType_t
,并且成功,因为参数的第一个n
字节实际上是surfaceType_t
。如果没有充分理由,不要这样做。
来自void*
的转换不会像在C中那样自动发生在C ++中。您可以使用reinterpret_cast
在两种不同类型的结构之间显式转换:
srfPoly_t* mySrfPoly_t;
surfaceType_t* mySurfaceType = reinterpret_cast<surfaceType_t*>(mySrfPoly_t);