Comment puis-je être capable de convertir un pointeur de classe en un pointeur générique tel que void *? Comme ce code est-il valide?
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;
}
Ceci est parfaitement valide. Voici ce que la norme a à dire à ce sujet:
§4.10 Conversions de pointeur
2 Une valeur rvalue de type "pointeur sur cv
T
", oùT
est un type d'objet, peut être convertie en une valeur rvalue de type "pointeur sur cvvoid
." Le résultat de la conversion d'un "pointeur vers cvT
" en un "pointeur vers cvvoid
" pointe vers le début de l'emplacement de stockage où réside l'objet de typeT
, comme si l'objet était le plus objet dérivé (1.8) de typeT
(c'est-à-dire, pas un sous-objet de classe de base).
ce qui signifie que vous pouvez convertir votre pointeur en classe en un pointeur vide. Et ...
§5.2.9 Coulée statique
10 Une valeur rvalue de type "pointeur sur cv
void
" peut être explicitement convertie en un pointeur sur un type d'objet. Une valeur de type pointeur sur objet convertie en "pointeur sur cvvoid
" et de retour sur le type de pointeur d'origine aura sa valeur d'origine.
ce qui signifie que vous pouvez utiliser static_cast
pour reconvertir un pointeur vide en un pointeur de classe d'origine.
J'espère que ça aide. Bonne chance!
En C++, vous n'avez pas besoin de la conversion statique pour obtenir à void*
:
int main()
{
CFoo* foo = new CFoo;
void* dt = foo;
tfunc(dt); // or tfunc(foo);
return 0;
}
NB: votre implémentation de tfunc()
est tout à fait correcte dans le sens où fait nécessite le casting.
Est-ce valide?
Oui, il est valide selon la norme § 5.2.9.7
Une valeur de type "pointeur sur cv1 vide" peut être convertie en une valeur de type "pointeur sur cv2 T", où T est un type d'objet et cv2 est identique à cv-qualification ou supérieur à cv-qualification. La valeur du pointeur null est convertie en la valeur du pointeur null du type de destination. Une valeur de type pointeur sur objet convertie en «pointeur sur cv void» et inversement, éventuellement avec une qualification cv différente, doit avoir sa valeur d'origine. [ Exemple:
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.
CFoo* foo = new CFoo;
void* dt = (void*)foo;