2016-02-03 2 views
0

J'ai affaire à un cas particulier où je ne peux pas utiliser dynamic_cast directement parce que l'objet est un void*. Utilise d'abord static_cast dessus et puis dynamic_cast (sur le résultat de la static_cast) mauvaise pratique? Est-ce faux?Utilisation static_cast puis dynamic_cast

Voici un exemple de ce que je parle:

MyClass* CastVoidPtr(void* pVoidPtr) 
{ 
    // casting it to MyClass so we could use dynamic_cast 
    MyClass* pTemp = static_cast<MyClass*>(pVoidPtr); 

    // returning the actual result that will make sure that we have a MyClass object or a nullptr 
    return dynamic_cast<MyClass*>(pTemp); 
} 
+3

'pTemp' est déjà un' 'MyClass *, qu'attendez-vous de la' dynamic_cast' à faire ici? Votre commentaire n'a pas de sens - si 'pVoidPtr' était un nullptr, alors' pTemp' le serait aussi, donc vous pourriez tout simplement le renvoyer. – Barry

+0

si 'pVoidPtr' n'est pas du type' MyClass', 'pTemp' ne sera-t-il pas non nul? –

+0

Commentaire original: Juste pour améliorer le commentaire de @ Barry: 'return dynamic_cast (pVoidPtr);' doit faire le travail. Voir les réponses pour plus de détails. Commentaire édité: Oh je ne savais pas que ce ne serait pas possible.Oublie mon commentaire. –

Répondre

3

Cela dépendra de la façon dont le pointeur a être un void* pour commencer. Si elle a été castée au void* du même type que le cast (ici MyClass*), alors oui, cette distribution est bien et fonctionne comme prévu;

De cppreference on static_cast:

A prvalue de pointeur de type à void (éventuellement cv-qualifié) peut être converti en pointeur vers un type quelconque. Si la valeur du pointeur d'origine satisfait à l'exigence d'alignement du type cible, la valeur du pointeur qui en résulte est inchangée, sinon elle n'est pas spécifiée. La conversion de n'importe quel pointeur en pointeur vers void et retour en pointeur vers le type d'origine (ou plus qualifié cv) préserve sa valeur d'origine.

L'utilisation static_cast de cette manière est essentiellement dire au compilateur « Je sais que c'est ce type - faites-moi confiance », et le compilateur oblige. Le dynamic_cast peut ensuite être évalué après cela. Il est généralement utilisé pour convertir un type plus dérivé. Ici, vous lancez le même type - il ne fait rien de particulièrement utile. Si le type était un type plus dérivé (par exemple MySpecialisedClass), alors ce serait bien.


En l'état actuel, la fonction peut être simplifiée:

MyClass* CastVoidPtr(void* pVoidPtr) 
{ 
    return static_cast<MyClass*>(pVoidPtr); 
} 

Ou tout simplement utiliser un static_cast<> nu.


Une note de côté; vaut la peine de mentionner ici pour l'exhaustivité est que reinterpret_cast has similar functionality;

Tout pointeur vers objet de type T1 peut être converti en pointeur à l'objet d'un autre type cv T2. Ceci est exactement équivalent à static_cast<cv T2*>(static_cast<cv void*>(expression)) (ce qui implique que si l'exigence d'alignement de T2 n'est pas plus stricte que T1, la valeur du pointeur ne change pas et la conversion du pointeur résultant en son type d'origine donne la valeur d'origine). Dans tous les cas, le pointeur résultant ne peut être déréférencé en toute sécurité si cela est autorisé par les règles d'aliasing de type ...