Duplicata possible:
Dois-je utiliser static_cast ou reinterpret_cast lors de la diffusion d'un void * vers quoi que ce soit
Dans ce programme, j'ai un void *
en tant que paramètre et que vous souhaitez convertir en un type spécifique. Mais je ne sais pas quel "symbole de casting" utiliser. Tous les deux static_cast
ou reinterpret_cast
travail. Quel est le meilleur? Lequel le Standard C++ recommande-t-il?
typedef struct
{
int a;
}A, *PA;
int foo(void* a) // the real type of a is A*
{
A* pA = static_cast<A*>(a); // or A* pA = reinterpret_cast<A*>(a);?
return pA->a;
}
Voici
A* pA = static_cast<A*>(a);
ou
A* pA = reinterpret_cast<A*>(a);
plus approprié?
Le static_cast
Est plus approprié pour convertir un void*
En un pointeur d'un autre type.
static_cast
Est la distribution de choix lorsqu'il existe une conversion naturelle et intuitive entre deux types qui n'est pas nécessairement garantie de fonctionner au moment de l'exécution. Par exemple, vous pouvez utiliser static_cast
Pour convertir des pointeurs de classe de base en pointeurs de classe dérivés, ce qui est une conversion qui a du sens dans certains cas mais qui ne peut pas être vérifiée avant l'exécution. De même, vous pouvez utiliser static_cast
Pour convertir d'un int
en char
, qui est bien défini mais peut entraîner une perte de précision lors de son exécution.
reinterpret_cast
, D'un autre côté, est un opérateur de casting conçu pour effectuer des conversions qui ne sont fondamentalement ni sûres ni portables. Par exemple, vous pouvez utiliser reinterpret_cast
Pour passer d'un void *
À un int
, ce qui fonctionnera correctement si votre système possède justement sizeof (void*)
≤ sizeof (int)
. Vous pouvez également utiliser reinterpret_cast
Pour convertir un float*
En un int*
Ou vice-versa, qui est spécifique à la plate-forme car les représentations particulières de float
s et int
s ne sont pas garantis d'avoir quelque chose en commun les uns avec les autres.
En bref, si jamais vous vous retrouvez en train de faire une conversion dans laquelle le transtypage est logiquement significatif mais peut ne pas nécessairement réussir au moment de l'exécution, évitez reinterpret_cast
. static_cast
Est un bon choix si vous avez une connaissance préalable que la distribution va fonctionner au moment de l'exécution et communique au compilateur "Je sais que cela pourrait ne pas fonctionner, mais au moins cela a du sens et j'ai un raison de croire qu'il fera correctement la bonne chose à l'exécution. " Le compilateur peut ensuite vérifier que la conversion est entre des types liés, signalant une erreur de compilation si ce n'est pas le cas. L'utilisation de reinterpret_cast
Pour ce faire avec les conversions de pointeurs contourne complètement le contrôle de sécurité au moment de la compilation.
Il y a quelques cas où vous voudrez peut-être utiliser un dynamic_cast
Au lieu d'un static_cast
, Mais ceux-ci impliquent principalement des transtypages dans une hiérarchie de classes et (rarement) concernent directement void*
.
Quant à celui qui est préféré par la spécification, ni l'un ni l'autre n'est trop mentionné comme "le bon à utiliser" (ou du moins, je ne me souviens pas que l'un d'eux ait été mentionné de cette façon.) Cependant, je pense que la spécification veut que vous le fassiez utilisez static_cast
sur reinterpret_cast
. Par exemple, lorsque vous utilisez une distribution de style C, comme dans
A* ptr = (A*) myVoidPointer;
L'ordre des opérateurs de transtypage essayés essaie toujours d'utiliser un static_cast
Avant un reinterpret_cast
, Ce qui est le comportement que vous souhaitez puisque reinterpret_cast
N'est pas garanti d'être portable.
Utilisation static_cast
pour ça. Seulement dans les cas les plus rares où il n'y a pas d'autre moyen, utilisez reinterpret_cast
.
Vous avez probablement obtenu que void*
avec conversion implicite, vous devez donc utiliser static_cast
car il est le plus proche de la conversion implicite.
Si vous effectuez un cast le long d'une hiérarchie de classes, utilisez dynamic_cast
- il vérifie que l'objet réel est compatible avec le type vers lequel vous effectuez le cast.