Quelle est la différence entre static_cast <> et le casting de style C?

Réponses:

217

Les transtypages de style C ++ sont vérifiés par le compilateur. Les conversions de style C ne le sont pas et peuvent échouer lors de l'exécution.

En outre, les conversions de style c ++ peuvent être recherchées facilement, alors qu'il est très difficile de rechercher des conversions de style c.

Un autre gros avantage est que les 4 modèles de style C ++ différents expriment plus clairement l'intention du programmeur.

Lors de l'écriture de C ++, j'utiliserais presque toujours ceux de C ++ sur le style C.

Glen
la source
67
Les seuls transtypages pouvant échouer à l'exécution sont les dynamic_casts.
R. Martinho Fernandes
12
C ++ reinterpret_cast <T> (U) peut échouer au moment de l'exécution à peu près de la même manière que les transtypages de style C, et ils sont tous très différents de la façon dont dynamic_cast <T> (U) échoue.
Christopher Smith
20
˗1 la conversion C normale (int)somethingne peut pas échouer - vous obtenez une conversion en int ou une erreur de compilation.
Tomáš Zato - Rétablir Monica
2
Pouvez-vous expliquer pourquoi les conversions C ++ peuvent être recherchées plus facilement que les conversions C?
Minh Tran
3
@MinhTran Pour le style C ++, vous pouvez rechercher le mot-clé "cast" à travers vos fichiers source. Mais voulez-vous faire avec les modèles de style C?
huangzonghao
176

En bref :

  1. static_cast<>() vous donne une capacité de vérification du temps de compilation, contrairement à la distribution de style C.
  2. static_cast<>() est plus lisible et peut être repéré facilement n'importe où dans un code source C ++, le cast C_Style n'est pas.
  3. Les intentions sont beaucoup mieux exprimées à l'aide de modèles C ++.

Plus d'explication :

La distribution statique effectue des conversions entre les types compatibles . Il est similaire à la distribution de style C, mais est plus restrictif. Par exemple, la conversion de style C permettrait à un pointeur entier de pointer vers un caractère.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Étant donné que cela se traduit par un pointeur de 4 octets (un pointeur vers un type de données de 4 octets) pointant vers 1 octet de mémoire allouée, l'écriture dans ce pointeur provoquera une erreur d'exécution ou écrasera une partie de la mémoire adjacente.

*p = 5; // run-time error: stack corruption

Contrairement à la distribution de style C, la conversion statique permettra au compilateur de vérifier que les types de données de pointeur et de pointe sont compatibles, ce qui permet au programmeur de détecter cette affectation de pointeur incorrecte lors de la compilation.

int *q = static_cast<int*>(&c); // compile-time error

Vous pouvez également consulter cette page pour plus d'explications sur les conversions C ++: Cliquez ici

Breeze
la source
17
Je pense qu'au lieu de "pointeur de 4 octets", vous vouliez dire "pointeur vers un type de données de 4 octets"
iheanyi
mais il permet int q = static_cast <int> (c);
TonyParker
3
@TonyParker C'est parce qu'il n'y a rien de mal à cette ligne.
Braden Best
15

Voir Comparaison des opérateurs de transtypage C ++ .

Cependant, l'utilisation de la même syntaxe pour une variété d'opérations de transtypage différentes peut rendre l'intention du programmeur peu claire.

De plus, il peut être difficile de trouver un type spécifique de transtypage dans une grande base de code.

la généralité de la distribution de style C peut être exagérée dans les situations où tout ce qui est nécessaire est une simple conversion. La possibilité de choisir entre plusieurs opérateurs de casting différents de différents degrés de puissance peut empêcher les programmeurs de lancer par inadvertance un type incorrect.

Eugene Yokota
la source
14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}
Rishi Khaneja
la source
5
Pourriez-vous élaborer davantage votre réponse en ajoutant un peu plus de description sur la solution que vous proposez?
abarisone
1
Je pense que la réponse montre que "static_casts" vérifie les conversions de type pour s'assurer qu'elles se trouvent le long de chemins valides dans le graphique de la hiérarchie. Dans cet exemple particulier, la conversion de A * en B * ou B * en A * est autorisée car A et B forment un chemin dans le graphique hiérarchique. C * n'est pas sur le chemin, donc static_cast produira une erreur au moment de la compilation. Sidenote: Il peut être intéressant de noter que la conversion de A * en B * peut entraîner NULL avec un dynamic_cast au moment de l'exécution en fonction du véritable objet sous-jacent.
Tommy Chen
7

Un excellent article expliquant les différentes conversions en C / C ++ et ce que fait vraiment la distribution de style C: https://anteru.net/blog/2007/12/18/200/index.html

Casting de style C, utilisant la syntaxe de variable (type). Le pire jamais inventé. Cela essaie de faire les transtypages suivants, dans cet ordre: (voir aussi C ++ Standard, 5.4 expr.cast paragraphe 5)

  1. const_cast
  2. static_cast
  3. static_cast suivi de const_cast
  4. reinterpret_cast
  5. reinterpret_castfollowed par const_cast
Ying Xiong
la source
5

static_castvérifie au moment de la compilation que la conversion n'est pas entre des types manifestement incompatibles. Contrairement à dynamic_cast, aucune vérification de la compatibilité des types n'est effectuée au moment de l'exécution. Aussi,static_cast conversion n'est pas nécessairement sûre.

static_cast est utilisé pour convertir un pointeur en classe de base en un pointeur en classe dérivée, ou entre des types natifs, tels que enum en int ou float en int.

L'utilisateur de static_cast doit s'assurer que la conversion est sûre.

La conversion de style C n'effectue aucune vérification, ni lors de la compilation ni lors de l'exécution.

kiriloff
la source
3

Puisqu'il existe de nombreux types de transtypages chacun avec une sémantique différente, static_cast <> vous permet de dire "Je fais une conversion légale d'un type à un autre" comme d'int à double. Un casting de style C simple peut signifier beaucoup de choses. Êtes-vous un casting haut / bas? Réinterprétez-vous un pointeur?

Doug T.
la source