Arm*_*yan 29
void*
是这样一个指针,任何指针都可以隐式转换为void*
.
例如;
int* p = new int;
void* pv = p; //OK;
p = pv; //Error, the opposite conversion must be explicit in C++ (in C this is OK too)
Run Code Online (Sandbox Code Playgroud)
另请注意,void*
没有a ,指向const的指针无法转换为const_cast
例如
const int * pc = new const int(4);
void * pv = pc; //Error
const void* pcv = pc; //OK
Run Code Online (Sandbox Code Playgroud)
心连心.
Ben*_*ird 17
在C中,任何指针都可以指向内存中的任何地址,因为类型信息在指针中,而不在目标中.所以int*只是一个指向某个内存位置的指针,它被认为是一个整数.void*指针,只是指向未定义类型的内存位置的指针(可以是任何内容).
因此任何指针都可以转换为void*,但不是相反,因为转换(例如)一个指向int指针的void指针正在向它添加信息 - 通过执行转换,您声明目标数据是整数,所以你必须明确地说出这一点.反过来说,你所做的只是说int指针是某种指针,这很好.
它在C++中可能是相同的.
Avoid *
可以指向内存中任何类似数据的东西,比如整数值、结构体或其他任何东西。
但请注意,您不能在void *
和 函数指针之间自由转换。这是因为在某些体系结构上,代码与数据不在同一地址空间中,因此代码的地址 0x00000000 可能与数据的地址 0x00000000 引用不同的位集。
可以实现编译器,使其void *
足够大以记住差异,但总的来说,我认为这没有完成,而是语言未定义它。
在典型/主流计算机上,代码和数据驻留在同一地址空间中,如果您将函数指针存储到 a 中,编译器通常会生成合理的结果void *
,因为它非常有用。
除了其他用户已经说过的其他内容之外,void*
它通常用于回调定义.这允许您的回调接收任何类型的用户数据,包括您自己定义的对象/结构,在使用之前应该将其转换为适当的类型:
void my_player_cb(int reason, void* data)
{
Player_t* player = (Player_t*)data;
if (reason == END_OF_FILE)
{
if (player->playing)
{
// execute stop(), release allocated resources and
// start() playing the next file on the list
}
}
}
Run Code Online (Sandbox Code Playgroud)