基本含义
void*在The C++ Programming Language中解释为:pointer to an object of unknown type. 即指向一未知类型的对象。
那么我们什么时候会用到或者见到void*指针呢?
在一些底层的代码中,我们可能需要处理一片内存,但是我们并不知道这一块内存存储的到底是什么类型的对象,在之后的例子中将会以memset
讲解。
使用规则
- void*可以被赋值为任意类型对象的指针(隐式转化),除了指向函数或者成员的指针
- void*可以被另一个void*赋值
- void*之间可以比较是否相等
- void*可以被显式转化为其他类型
- 除以上的4点操作之外的其他操作都是不安全的
例1
代码引用自The C++ Programming Language
void f(int *p) {
void* pi = p; //implicit conversion from int* to void*
*pv; //error: can't redeference void*
++pv; //error: can't increment void* (the size of the object pointed to is unknown)
int* pi2 = static_cast<void*>(pi); //explicit conversion back to int*
double* pd1 = pv; //error
double* pd2 = pi; //error: the type of the pointers is not equal
double* pd3 = static_cast<void*>(pi); //unsafe
}
例2
memset
的原型为:void * memset ( void * ptr, int value, size_t num );
其中第一个参数为void*
,因为我们并不知道要memset
的到底是一个int数组,还是char型数组之类的,所以我们用void*
来代表第一个参数,在C标准库一书中,memset
的实现如下:
void* memset(void* ptr, int value, size_t num) {
const unsigned char uc = value; //convert int to unsigned char
unsigned char* p; //void* will be implicit convert to unsigned char*
for (p = ptr; num > 0; num--, p++) {
*p = value;
}
}
在函数内的第2行,我们声明一个unsigned char*
类型的指针p,并在循环内,将其void*
隐式转化为unsigned char*
型。
但是该代码只能在gcc下编译通过,如果用g++的话,必须要进行显式类型转化,代码如下:
void* memset(void* ptr, int value, size_t num) {
const unsigned char uc = value;
unsigned char* p;
for (p = static_cast<unsigned char*>(ptr); num > 0; num--, p++) {
*p = value;
}
}
以及通过上面的代码,我们不难看出为什么对int
型数组进行内存初始化:memset(a, 1, sizeof(a))
答案不对了= =