c++ - punteros - Lanzar puntero de clase al puntero de vacío
que es un apuntador en informatica (4)
¿Cómo puedo lanzar un puntero de clase a un puntero genérico como void *? Al igual que este código es válido?
class CFoo
{
int a;
public:
CFoo():a(1){}
~CFoo(){}
getNum(){return a;}
};
void tfunc(void* data)
{
CFoo* foo = static_cast<CFoo*>(data);
std::cout << "Number: " << foo->getNum();
delete foo;
}
int main()
{
CFoo* foo = new CFoo;
void* dt = static_cast<void*>(foo);
tfunc(dt); // or tfunc(static_cast<void*>(food));
return 0;
}
Es esto valido?
Sí, es válido según el § 5.2.9.7 estándar
Un prvalue de tipo "puntero a cv1 void" se puede convertir a un prvalue de tipo "puntero a cv2 T", donde T es un tipo de objeto y cv2 es la misma calificación cv, o una calificación cv mayor que, cv1. El valor del puntero nulo se convierte en el valor del puntero nulo del tipo de destino. Un valor de tipo puntero a objeto convertido a "puntero a cv void" y viceversa, posiblemente con diferente cv-qualification, tendrá su valor original. [Ejemplo:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
bool b = p1 == p2; // b will have the value true.
Esto es perfectamente válido. Esto es lo que el estándar tiene que decir al respecto:
§4.10 Conversiones de punteros
2 Un valor de tipo "puntero a cv
T
", dondeT
es un tipo de objeto, se puede convertir a un valor r de tipo "puntero a cvvoid
". El resultado de convertir un "puntero a cvT
" en un "puntero a cvvoid
" apunta al inicio de la ubicación de almacenamiento donde reside el objeto de tipoT
, como si el objeto fuera el más derivado (1.8) del tipoT
(es decir, no es un subobjeto de clase base).
lo que significa que puede convertir su puntero a clase en un puntero de vacío. Y ...
§5.2.9 Elenco estático
10 Un valor de tipo "puntero a cv
void
" puede convertirse explícitamente en un puntero al tipo de objeto. Un valor de tipo puntero a objeto convertido a "puntero a cvvoid
" y de vuelta al tipo de puntero original tendrá su valor original.
lo que significa que puede usar static_cast
para convertir un puntero void a un puntero de clase original.
Espero eso ayude. ¡Buena suerte!
CFoo* foo = new CFoo;
void* dt = (void*)foo;
En C ++ no necesitas el lanzamiento estático para obtener el void*
:
int main()
{
CFoo* foo = new CFoo;
void* dt = foo;
tfunc(dt); // or tfunc(foo);
return 0;
}
NB: su implementación de tfunc()
es bastante correcta ya que necesita el elenco.