Quels sont les usages appropriés de :
- ``
- ``
- ``
- ``
- Cast de style C``
- Cast de style fonction``
et comment on décide celle à utiliser dans un cas concret ?
Quels sont les usages appropriés de :
et comment on décide celle à utiliser dans un cas concret ?
static_cast
est le casting d'abord, vous devriez essayer d'utiliser. Il fait des choses comme les conversions implicites entre les types (tels que int, float, ou un pointeur de type void*), et il peut également appeler les fonctions de conversion explicite (ou implicite). Dans de nombreux cas, en indiquant expressément static_cast
n'est pas nécessaire, mais il est important de noter que l' T(something)
syntaxe est équivalente à (T)something
et doit être évitée (plus sur cela plus tard). Un T(something, something_else)
est sûr, cependant, et de la garantie d'appeler le constructeur.
static_cast
pouvez également exprimés à travers des hiérarchies d'héritage. Il est inutile lors de la coulée vers le haut (une classe de base), mais lors de la coulée vers le bas, il peut être utilisé tant qu'il n'a pas jeté par virtual
d'héritage. Il ne fait pas de vérification, cependant, et c'est un comportement indéfini d' static_cast
vers le bas de la hiérarchie à un type qui n'est en fait pas le type de l'objet.
const_cast
peut être utilisé pour supprimer ou ajouter des const
à une variable; aucune autre C++ cast est capable de le retirer (même pas reinterpret_cast
). Il est important de noter que la modification d'un anciennement const
de la valeur n'est pas définie si la variable d'origine, est const
; si vous l'utilisez pour prendre l' const
off une référence à quelque chose qui n'était pas déclarée avec const
, c'est sûr. Cela peut être utile en cas de surcharge des fonctions de membre basée sur const
, par exemple. Il peut également être utilisé pour ajouter de l' const
à un objet, comme pour appeler une fonction membre de la surcharge.
const_cast
fonctionne aussi de la même façon sur volatile
, même si c'est moins fréquent.
dynamic_cast
est presque exclusivement utilisé pour la manipulation de polymorphisme. Vous pouvez jeter un pointeur ou une référence à tout type polymorphe à tout autre type de classe (un type polymorphe a au moins une fonction virtuelle, déclaré ou hérité). Vous pouvez l'utiliser pour plus que juste de coulée vers le bas -- vous pouvez lancer sur le côté ou même d'une autre chaîne. L' dynamic_cast
quête de l'objet désiré et de le retourner si possible. Si il ne peut pas, il sera de retour NULL
dans le cas d'un pointeur, ou de jeter std::bad_cast
dans le cas de référence.
dynamic_cast
a certaines limitations. Il ne fonctionne pas si il y a plusieurs objets de même type dans la hiérarchie d'héritage (la soi-disant "tant redoutée de diamant") et que vous n'utilisez pas virtual
d'héritage. Il a également ne peut que passer par le public de l'héritage - il échouera toujours à voyager à travers l' protected
ou private
d'héritage. C'est rarement un problème, cependant, que de telles formes d'héritage sont rares.
reinterpret_cast
est le plus dangereux de fonte, et doit être utilisé avec beaucoup de parcimonie. Il tourne un type vers un autre - comme la coulée de la valeur d'un pointeur à un autre, ou le stockage d'un pointeur dans un int
, ou toutes autres sortes de choses désagréables. En grande partie, la seule garantie que vous obtenez avec reinterpret_cast
, c'est que normalement, si vous lancez le résultat en arrière à l'original, vous obtiendrez exactement la même valeur (mais pas si le type intermédiaire est plus petit que le type d'origine). Il y a un certain nombre de conversions reinterpret_cast
ne peuvent pas faire, trop. Il est utilisé principalement pour la particulièrement bizarre conversions et peu de manipulations, comme transformer un flux de données brutes en données réelles, ou le stockage des données dans les bits de poids faible de l'alignement de pointeur.
C casts
sont des distributions à l'aide de (type)object
ou type(object)
. Un style C cast est définie comme étant le premier de la suivante qui réussit:
const_cast
static_cast
(mais en ignorant les restrictions d'accès)static_cast
(voir ci-dessus), alors const_cast
reinterpret_cast
reinterpret_cast
, alors const_cast
Il peut donc être utilisé comme un remplacement pour les autres distributions, dans certains cas, mais qui peut être extrêmement dangereux en raison de la capacité à déléguer en reinterpret_cast
, et celles-ci devraient être privilégiées lors de la conversion explicite est nécessaire, sauf si vous savez static_cast
réussira ou reinterpret_cast
échouent. Même ensuite, tenir compte de la plus, la plus explicite de l'option.
C-style jette également ignorer de contrôle d'accès lors de l'exécution d'un static_cast
, ce qui signifie qu'ils ont la capacité d'effectuer une opération qu'aucune autre conversion peut. C'est surtout une bidouille, même si, et dans mon esprit, c'est juste une autre raison pour éviter de style C jette.
Utilisation `` pour convertir les pointeurs et références au sein d’une hiérarchie d’héritage.
Utilisation `` pour les conversions de type ordinaire.
Utilisation `` pour réinterpréter à basse altitude des modèles binaires. Utiliser avec une extrême prudence.
Utilisation pour effectuer le cast away
. Pour éviter cela que si vous êtes coincé à l’aide d’une API de const-incorrecte.
(Beaucoup de théorique et conceptuel de l'explication qui a été donnée ci-dessus)
Ci-dessous sont quelques-uns des exemples pratiques lorsque j'ai utilisé static_cast, dynamic_cast ,const_cast ,reinterpret_cast.
(Aussi renvoie cela pour comprendre l'explication : http://www.cplusplus.com/doc/tutorial/typecasting/)
statique de la distribution :
OnEventData(void* pData)
{
......
// pData is a void* pData,
// EventData is a structure e.g.
// typedef struct _EventData {
// std::string id;
// std:: string remote_id;
// } EventData;
// On Some Situation a void pointer *pData
// has been static_casted as
// EventData* pointer
EventData *evtdata = static_cast<EventData*>(pData);
.....
}
dynamic_cast :
void DebugLog::OnMessage(Message *msg)
{
// typecasting the message data based on the message type
switch (msg->message_id)
{
case MSG_DEBUG_OUT:
{
DebugMsgData *data = dynamic_cast<DebugMsgData*>(msg->pdata);
}
case MSG_XYZ:
{
XYZMsgData *data = dynamic_cast<XYZMsgData*>(msg->pdata);
}
.....
}
}
const_cast :
// *Passwd declared as a const
const unsigned char *Passwd
// on some situation it require to remove its constness
const_cast<unsigned char*>(Passwd)
reinterpret_cast:
typedef unsigned short uint16;
// Lecture des Octets renvoie que 2 octets ai lu.
bool ByteBuffer::ReadUInt16(uint16& val) {
return ReadBytes(reinterpret_cast<char*>(&val), 2);
}
N' cette réponse à votre question?
Je n'ai jamais utilisé reinterpret_cast
, et de se demander si dans un cas il n'est pas une odeur de mauvaise conception. Dans la base de code, je travaille sur dynamic_cast
est beaucoup utilisé. La différence avec l' static_cast
est qu'un dynamic_cast
ne contrôle d'exécution qui peut (safer) ou ne peuvent pas (plus les frais généraux) être ce que vous voulez (voir msdn).
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.