¿Puntero a vacío en C ++?
-
03-07-2019 - |
Pregunta
Estoy leyendo un código en la implementación de Ogre3D y no entiendo qué es un void *
variable de tipo significa. ¿Qué significa un puntero a void
en C ++?
Solución
Un puntero al vacío, void *
puede apuntar a cualquier objeto:
int a = 5;
void *p = &a;
double b = 3.14;
p = &b;
No puede desreferenciar, incrementar o disminuir ese puntero, porque no sabe a qué tipo apunta. La idea es que void *
se puede usar para funciones como memcpy
que simplemente copian bloques de memoria y no les importa el tipo que copian.
Otros consejos
Es solo un puntero genérico, usado para pasar datos cuando no se conoce el tipo. Tienes que convertirlo en el tipo correcto para poder usarlo.
Es un puntero en bruto a un punto en la memoria. No permite ninguna aritmética de punteros como char * o int *.
Aquí hay algunos ejemplos de uso
Es un puntero a cualquier cosa , solo una parte de la memoria con la que puedes jugar, podría ser un objeto, podría ser un char. Tienes que lanzar para hacer algo útil con él.
Aprovechando mi publicación anterior ...
ATENCIÓN: Todas las direcciones de memoria aquí son ficticias. Solo los invento para ilustrar un punto.
Dado:
int data[] = {10,11,12};
Ahora tenemos:
0xffff0000-0xffff0003 with a value of (int)(10)
0xffff0004-0xffff0007 with a value of (int)(11)
0xffff0008-0xffff000b with a value of (int)(12)
(No voy a entrar en el orden de los bytes big-endian vs little-endian aquí.)
Si tenemos:
int * p = data;
Ahora tenemos otra ubicación de memoria en otro lugar, por ejemplo:
0xaaaa0000-0xaaaa0003 with a value of (int*)0xffff0000
Podemos usar p [1] [o * (p + 1)] para referirnos a * (int *) (0xffff0004) [= 11] como sizeof (int) = 4 y 0xffff0000 + sizeof (int) = 0xffff0004.
Si tenemos:
void * v = data;
Ahora tenemos otra ubicación de memoria en otro lugar, por ejemplo:
0xbbbb0000-0xbbbb0003 with a value of (void*)0xffff0000.
Sin embargo, void no tiene ninguna información asociada de sizeof (). No podemos incrementar o disminuir el puntero. No podemos dejar de tener acceso a los datos almacenados en 0xffff0000. Solo podemos utilizar el valor como una dirección de memoria sin procesar.
Si queremos usar los datos almacenados en (void *) 0xffff0000, primero debemos convertirlos a un tipo apropiado.
Dicho esto, (void *) sigue siendo bastante útil como medio para pasar direcciones a estructuras de datos arbitrarias. Por ejemplo, memset (). No importa si estoy eliminando un struct tm o un struct sockaddr . Solo necesitamos un puntero a la estructura y su tamaño.
(Esto debería ser evidente, pero ... Tenga cuidado al utilizar memset para poner a cero una instancia de clase y, al hacerlo, sobrescribir la tabla de punteros virtuales).
Un puntero vacío no puede apuntar a un miembro de la clase en C ++.