void指针:C和C ++之间的区别
我试图理解C和C ++之间关于void指针的区别。 以下用C语言编译但不用C ++编译(用gcc / g ++ -ansi -pedantic -Wall完成的所有编译):
int* p = malloc(sizeof(int));
因为malloc
返回void*
,C允许分配给int*
而C允许这样做。
但是,这里:
void foo(void* vptr) { } int main() { int* p = (int*) malloc(sizeof(int)); foo(p); return 0; }
C ++和C都编译它没有抱怨。 为什么?
K&R2说:
任何指向对象的指针都可以转换为
void *
类型而不会丢失信息。 如果结果转换回原始指针类型,则恢复原始指针。
这很好地总结了C中的void*
转换.C ++标准规定了什么?
在C中,与void*
之间的指针转换始终是隐式的。
在C ++中,从T*
到void*
转换是隐式的,但对其他任何东西的void*
都需要强制转换。
C ++比C更强类型。许多转换,特别是那些暗示对值的不同解释的转换,需要显式转换。 C ++中的new运算符是一种类型安全的方法,可以在堆上分配内存,而无需显式转换。
理解指针类型转换并不需要执行额外的CPU指令是很有用的。 在编译期间对它们进行分析,以了解开发人员的意图。 void *
是一个不透明的指针。 它只是说尖头物体的类型是未知的。 C是弱类型的。 它允许隐式地在( void *
)和任何( T*
)之间直接转换。 C ++是强类型的。 从( void *
)到( T*
)的转换对于强类型语言来说并不是真正的好例子。 但是C ++必须与C保持向后兼容,因此它必须允许这样的转换。 那么指导原则是:明确比隐含更好。 因此,如果您希望将( void*
)转换为某个特定( T*
)指针,则需要在代码中显式地写入它。 从( T*
)到( void*
)的转换不需要显式转换,因为没有什么可以直接对(void *)指针执行(可以调用free())。 因此( T*
)到( void*
)转换非常安全。