web-dev-qa-db-fra.com

moulages de style c ou moulages de style c ++

Alors qu'est-ce que vous utilisez?

int anInt = (int)aFloat;

ou

int anInt = static_cast<int>(aFloat);
// and its brethren

Et, plus important encore, pourquoi?

21
bastibe

Tout d'abord, comprenez que ces lignes ne sont pas équivalentes .

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

Ce qui se passe ici, c'est que le programmeur demande au compilateur de faire tout ce qu'il peut pour faire le cast.

La différence est importante car l'utilisation de static_cast ne demandera qu'un type de base "sûr" pour la conversion, où reinterpret_cast se convertira en n'importe quoi, peut-être en mappant simplement la disposition de mémoire souhaitée sur la mémoire de l'objet donné.

Donc, comme le "filtre" n'est pas le même, utiliser un cast spécifique est plus clair et sûr que d'utiliser le cast C, si vous comptez sur le compilateur (ou implémentation d'exécution si vous utilisez dynamic_cast) pour vous dire où vous avez fait quelque chose de mal , en évitant le cast C et reinterepret_cast.

Maintenant que c'est plus clair, il y a une autre chose: static_cast, reinterpret_cast, const_cast et dynamic_cast sont plus faciles à rechercher .

Et le point ultime: ils sont moches . C'est voulu. Le code potentiellement bogué, les odeurs de code, les "astuces" évidentes qui pourraient générer des bogues, sont plus faciles à suivre lorsqu'il est associé à un aspect laid. Le mauvais code doit être laid .

C'est "par conception". Et cela permet au développeur de savoir où il aurait pu mieux faire les choses (en évitant totalement les lancers, si ce n'est vraiment nécessaire) et où c'est bien mais "documenté" dans le code en le "marquant" comme laid.

Une raison secondaire de l'introduction de la distribution de nouveau style était que les moulages de style C sont très difficiles à repérer dans un programme. Par exemple, vous ne pouvez pas rechercher facilement des conversions à l'aide d'un éditeur ordinaire ou d'un traitement de texte. Cette quasi-invisibilité des moulages de style C est particulièrement regrettable car ils sont si potentiellement dommageables. Une opération laide devrait avoir une forme syntaxique laide. Cette observation faisait partie de la raison du choix de la syntaxe pour les transtypages de nouveau style. Une autre raison était que les conversions de nouveau style correspondent à la notation du modèle, afin que les programmeurs puissent écrire leurs propres conversions, en particulier les conversions vérifiées au moment de l'exécution.

Peut-être, parce que static_cast est si moche et si difficile à taper, vous êtes plus susceptible de réfléchir à deux fois avant d'en utiliser un? Ce serait bien, car les conversions sont vraiment évitables dans le C++ moderne.

Source: Bjarne Stroustrup (créateur C++)

47
Klaim

Les transtypages C++ sont plus restrictifs (alors exprimez mieux votre intention et facilitez la révision du code, etc.). Ils sont également beaucoup plus faciles à rechercher, si jamais vous en avez besoin.

37
Bruce Stephens

Option C: une fonte de "style C++", car elle ne se distingue pas d'une construction:

int anInt = int(aFloat);

ou même:

int anInt(aFloat);

Cela mis à part, à part ces cas triviaux avec des primitives, qui sont bien compris, je préfère utiliser x_cast <> s plutôt que des transtypages de style C. Il y a trois raisons pour lesquelles:

  • Ils définissent plus précisément l'opération que le programmeur tentait d'effectuer.

  • Ils peuvent effectuer des actions que les transtypages de style C ne peuvent pas effectuer (en particulier dans le cas de dynamic_cast <>, qui peut effectuer une conversion croisée entre les branches d'une chaîne à héritage multiple).

  • Ils sont moches. Ils déclarent haut et fort que le programmeur travaille contre le système de type. Dans ce cas, c'est une bonne chose.

13
Kaz Dragon

J'ai quelques règles concernant les conversions de style C/C++:

  1. La désapplication d'un const doit toujours utiliser un const_cast. Pour des raisons évidentes. Malheureusement, ma règle de désappliquer un const provoquant le clavier à atteindre et à casser le doigt du programmeur n'a pas été approuvée.
  2. Tous les manigances de style de manipulation de bits auxquels les programmeurs s'adonnent lorsqu'ils se mettent au travail devraient utiliser reinterpret_cast. C'est vraiment le genre de distribution que C n'a pas: prétendre que les bits de cet entier sont en fait des bits de flotteur. Cela évite les désagréments comme (int)(*(int*)(&floatVar)).
  3. Si vous tapez les mots "dynamic_cast ", arrêtez et réévaluez la conception et la hiérarchie de votre classe polymorphe. Continuez à réévaluer la conception de la hiérarchie de vos classes jusqu'à ce que vous puissiez supprimer ces mots.
  4. Ne vous embêtez pas avec static_cast.

Le raisonnement derrière # 4 est simplement que cela n'a pas d'importance. Les circonstances qui ne rentrent pas dans les autres règles sont évidentes ou vraiment de bas niveau. Une conversion bien comprise de types simples comme int-to-float ne devrait pas nécessiter de syntaxe spéciale. Et si vous êtes dans les entrailles profondes et laides de quelque chose, eh bien, vous êtes dans les entrailles profondes et laides de quelque chose. Il n'est pas nécessaire d'attirer l'attention sur le fait que "ici, il y a des dragons", car les dents, les griffes et le feu le trahissaient déjà.

7
Nicol Bolas

Si vous écrivez du code en C, utilisez une fonte C. Si vous écrivez en C++, utilisez un cast C++.

Alors que la plupart des castings ne respectent pas la sécurité de type appropriée, ceux de C++ sont plus restrictifs, et vous êtes donc légèrement moins dangereux pour le type que vous ne le seriez avec un cast de C.

Je peux tolérer que quelqu'un utilise (T *) NULL pour forcer une surcharge ...

7
CashCow

Comme les articles ci-dessus le notent, la distribution C++ (statique) est un peu plus sûre dans la pratique.

Il pourrait être judicieux de rechercher plus d'informations sur les différents types de casting et leurs avantages et inconvénients.

Juste pour avoir plus d'informations sur pourquoi. .

http://en.wikipedia.org/wiki/Static_cast

http://en.wikipedia.org/wiki/Dynamic_cast

http://en.wikipedia.org/wiki/Reinterpret_cast

4
the JinX

Cela dépend vraiment de la langue avec laquelle je travaille, puisque vous savez ce qu'ils disent: à Rome, parle romain. Donc, si je programme en C, j'essaie d'utiliser les fonctionnalités C au maximum, mais si je programme en C++, je continue et j'utilise les fonctionnalités C++ au maximum, même si certaines personnes n'aiment pas cette approche car ils disent que cela rend le code "moins portable", je dis que je m'en fiche, je suis en C++ et je programme en C++, et j'ai besoin d'un compilateur entièrement compatible C++ pour compiler du code, sinon je travaillerais avec quelque chose de différent en premier lieu.

3
Coyote21

static_cast etc. ont été inventés en raison de problèmes avec les transtypages de style C lorsqu'ils sont utilisés dans les modèles. Si vous écrivez un modèle, ou si votre code peut plus tard être converti en modèle, c'est une bonne idée d'utiliser des transtypages de style C++. La raison en est que les transtypages de style C++ expriment mieux l'intention, donc ils donneront les résultats attendus dans les cas où les transtypages de style C feront la mauvaise chose (avec des types particuliers comme paramètres de modèle).

En dehors de cela, je dis utiliser des conversions de style C++ si vous avez un problème spécifique qui en a besoin - dynamic_cast est le plus courant, mais même ce n'est probablement pas une chose de tous les jours.

Autre chose, et une distribution de style C peut être un peu moins encombrante et aider à la lisibilité, ou peut-être pas en fonction de la familiarité du lecteur avec ce style de distribution de nos jours. À mon avis, ce n'est pas vraiment important, surtout une préférence personnelle, mais ne soyez pas surpris si certaines personnes n'aiment pas le style C.

Remarque finale - si vous avez besoin d'autant de transtypages que c'est un gros problème, vous faites probablement autre chose de mal. Il y a des exceptions à cela dans certains cas, mais la plupart des codes de haut niveau ne devraient pas avoir besoin de plusieurs transtypages (le cas échéant).

3
Steve314