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", dondeTes 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.