web-dev-qa-db-fra.com

Casting Class Pointer à Void Aiguille

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;
}
11
domlao

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 cv void." Le résultat de la conversion d'un "pointeur vers cv T" en un "pointeur vers cv void" pointe vers le début de l'emplacement de stockage où réside l'objet de type T, comme si l'objet était le plus objet dérivé (1.8) de type T (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 cv void" 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!

11
user405725

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.

6
quamrana

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.
1
billz
    CFoo* foo = new CFoo;
    void* dt = (void*)foo;
0
UfnCod3r