9
votes

Différence entre static_cast et (char *)

C'est ma première question :)

J'ai un fichier de pile, et je l'ai ouvert comme indiqué ci-dessous; p> xxx pré>

alors, je souhaite tenir 2 octets Données dans UNSIGNÉ INT HOLD; P>

unsigned int hold;
in . read((char*)(&hold), 2); 


2 commentaires

Dupliqué possible de Quelle est la différence entre static_cast < > et c style casting?


Tailleof (Unsigné Int) est normalement supérieur à 2, vous aurez donc des octets initialisés et certains octets ininitialisés dans votre Hold , ce qui n'est pas du tout utile.


5 Réponses :


3
votes
  • Tout d'abord, vous pouvez facilement rechercher _cast et trouver n'importe quel cas de C ++. La recherche de moules de style C est beaucoup plus difficile.
  • Deuxièmement - Si vous utilisez C ++ CASTS, vous devez choisir le bon. Dans votre cas, il est reterpret_cast .
    La coulée de style C fait tout.

    Vous pouvez également consulter ici: http://www.cplusplus.com/doc/tatudial / Typecasting / pour les différences des différentes counts C ++. Je recommande vivement seulement d'utiliser des moulages C ++. De cette façon, vous pouvez facilement trouver et les vérifier plus tard et vous êtes obligé de penser à ce que vous faites réellement là-bas. Cela améliore la qualité du code!


0 commentaires

12
votes

static_cast est une distribution plus sûre que la coulée de style C implicite. Si vous essayez de jeter une entité qui n'est pas compatible avec une autre, alors static_cast vous donne une erreur de temps de compilation différente de la distribution de style C implicite.

static_cast vous donne une erreur ici car ce que vous essayez de dire est de prendre un int et essayez de l'adapter dans un char , ce qui n'est pas possible. int a besoin de plus de mémoire que ce que Char occupe et la conversion ne peut pas être effectuée de manière sûre.

Si vous souhaitez toujours obtenir cela, vous pouvez utiliser REINERPRET_CAST , il vous permet de taper deux types de données complètement différents, mais ce n'est pas sûr.
La seule garantie que vous obtenez avec réinterpret_cast est que si vous lancez le résultat vers le type d'origine, vous obtiendrez la même valeur, mais aucune autre garantie de sécurité.


1 commentaires

+1 Pour l'explication, mais je mentionnerais Reterpret_cast ici.



1
votes

Vous auriez dû utiliser reterpret_cast au lieu de static_cast , car les types de données ne sont pas liés: vous pouvez convertir entre un pointeur vers un Sous-classe à une superclasse par exemple, ou entre int et long ou entre vide * et n'importe quel pointeur, mais non signé INT * < / code> à char * n'est pas "SAFE" et vous ne pouvez donc pas le faire avec static_cast .

La différence est que, dans C ++, vous avez différents types de mises:

  • static_cast qui concerne les conversions "sûres";

  • reterpret_cast qui est destiné aux conversions "dangereuses";

  • const_cast qui est destiné à supprimer un attribut const ;

  • dynamic_cast qui est destiné à la sous-section (casting d'un pointeur / référence d'une superclasse à une sous-classe).

    Le code de style C (char *) x peut signifier tous ces éléments ci-dessus, il n'est donc pas aussi clair que la C ++ moulage. En outre, il est facile à grep pour une distribution de style C ++ (juste Grep pour _cast ), mais il est assez difficile de rechercher toutes les couts de style C.


3 commentaires

const_cast est pas uniquement pour casting const mais aussi pour le moins communément connu / utilisé volatile aussi.


@Andreabergia: Notez que const_cast peut aussi ajouter const et volatile qualificatifs. (Pas qu'il y ait de nombreuses situations où cela serait utile, bien sûr.)


Une coulée de style C ne signifie jamais la même chose que dynamic_cast . (Sauf dans ces cas où static_cast et dynamic_cast faites la même chose qu'une conversion implicite.) Et static_cast n'est pas toujours "sûr": Par exemple, il peut être jeté de la base à une référence / pointe dérivée lorsque l'objet n'est pas réellement dérivé.



1
votes

Le static_cast est illégal ici; Vous coulez entre sans rapport Types de pointeur. La solution pour le faire compiler serait d'utiliser Reterpret_cast (qui est ce que (char *) se résout dans ce cas). Qui, bien sûr, vous dit que le code n'est pas portable, et en fait, Sauf si vous faites un travail de niveau très bas, il ne fonctionnera probablement pas correctement dans tous les cas.

Dans ce cas, bien sûr, vous lisez des données brutes et vous réclamez que c'est un non signé INT . Ce que ce n'est pas; les entrées de lecture sont des données brutes que vous toujours à convertir manuellement à tout ce dont vous avez besoin, selon le format utilisé lors de l'écriture du fichier. (Il n'y a pas de telle chose que données non formatées. Juste des données avec un sans papiers, non spécifiés ou format inconnu. L'entrée "non formatée" et la sortie dans iostream sont conçus pour lire et écrire des tampons char que vous formatez manuellement. Le besoin de reterpret_cast Voici un avertissement définitif que quelque chose ne va pas avec votre code. (Il y a des exceptions, de Bien sûr, mais ils sont rares entre.)


0 commentaires

0
votes

Vous obtiendrez généralement ces erreurs lors de l'E / S du fichier binaire en utilisant IFSTREAM ou ESTStream ou FRStream. Le problème est que ces flux ont des méthodes qui prennent const char * tandis que ce que vous avez est un tableau d'un autre type. Vous souhaitez écrire votre tableau en tant que bits binaires dans le fichier.

La manière traditionnelle de faire consiste à utiliser l'ancien casting de style (char *) qui dit fondamentalement que tout le pointeur que je le traite comme (char *) . Les anciennes coulées de style sont découragées par Pedantic / Mode strict . Pour vous débarrasser de ces avertissements, l'équivalent C ++ 11 est Reterpret_cast .

Je dirais, si vous faites des fichiers binaires d'E / S, vous savez déjà que les choses peuvent être portables ou non en fonction de la manière dont vous enregistrez le fichier dans un système d'exploitation et de lire dans un autre système d'exploitation. C'est toute une autre question, cependant, ne vous a pas fait peur par Reterpret_cast Parce que c'est ce que vous devez faire si vous souhaitez écrire des octets vers le fichier.


0 commentaires