2010-06-30 6 views
3

Est-ce moi, ou est-ce que C++ semble demander plus d'utilisation de l'instruction 'if' que C#?C++ if alternative alternatives

Je possède ce code de base et il contient beaucoup de choses comme celle-ci:

if (strcmp((char*)type,"double")==0) 

Je me suis demandé est-il pas un peu d'une « odeur de code » quand il y a juste trop de déclarations si? Je ne dis pas mauvais là, mais des choses comme des comparaisons de chaînes, avec beaucoup de chaînes impliquées, ne peuvent-elles être faites différemment?

Existe-t-il une alternative à l'écriture de séquences d'instructions if?

C'EST JUSTE UN EXEMPLE, IL PEUT ÊTRE QUELQUE NATURE QUE CE SI DE DÉCLARATIONS au lieu de:

if (string a == "blah") then bla 
if (string b == "blah") then blo 
+4

Voulez-vous dire la complexité des expressions plutôt que le nombre de «si»? Comment allez-vous sortir avec moins de «si» dans l'un contre l'autre lorsque vous avez besoin de branchez votre code? Votre question semble poser des questions sur les comparaisons de chaînes. Déroutant. –

+0

En fait, je voulais simplement savoir à propos de la présence de if dans de nombreux endroits, et la chaîne n'était qu'un exemple. J'ai beaucoup appris sur les pratiques de la POO et je pensais qu'il y avait peut-être plus de façons de faire de la POO; au lieu de si les déclarations. –

+0

Ah, je vois. Pourrait changer la question à 'C++ if alternative alternatives' pour obtenir de meilleures réponses dirigées. –

Répondre

5

C'est l'odeur de code.

Pour le minimiser, vous devez (dans ce cas) utiliser std::string s. Votre code devient alors:

#include <string> 
// [...] 
std::string type = "whatever"; 
// [...] 
if (type == "double") 

C'est presque identique à C# équivalent: pour compiler cet exemple de code dans le code C# il suffit de retirer le include et le std::.

Habituellement, si vous trouvez du code qui utilise char * directement en C++, c'est généralement qui le fait mal (sauf peut-être pour de rares exceptions).

Modifier: Mike DeSimone addressed the problem of further refactoring this dans sa réponse (donc je ne parlerai pas ici :)).

+1

+1 pour dire ne pas utiliser char * en C++. – Brian

+0

+1 pour l'odeur du code. Le casting de style ancien est une autre odeur de code à mon avis. –

1

Je ne pense pas que C++ nécessite plus de "ifs" que C#. Le nombre d'instructions if dans un programme est vraiment juste une question de style de codage. Vous pouvez toujours éliminer les ifs à travers des techniques comme le polymorphisme, les méthodes pilotées par table, etc. Ces mêmes techniques sont disponibles en C++ et en C#. S'il y a une différence entre les programmes écrits dans ces deux langues, je pense que cela a à voir avec la mentalité des programmeurs C# vs C++.

Notez que je ne recommande pas nécessairement l'élimination «si». Dans mon expérience, si les déclarations ont tendance à être plus claires que les alternatives. Pour adresser directement votre deuxième point: la façon d'éliminer les comparaisons de chaînes chaînées est d'utiliser une DFSA. La plupart du temps, cependant, les comparaisons de chaînes conviennent parfaitement.

+0

+1 ce n'est pas un problème C++ mais une façon d'écrire du code (dans n'importe quelle langue) –

13

La raison pour laquelle vous faites if (strcmp((char*)type,"double")==0) est parce que vous ne pouvez pas faire "double" une expression case et utiliser une instruction switch. Cela dit, si vous faites un lot de ces types de correspondances de chaînes, vous pouvez vouloir utiliser un std::map<std::string, int> ou quelque chose de similaire et ensuite utiliser la carte pour convertir la chaîne en un index que vous alimentez ensuite à switch.

Personnellement, dans ces cas, je suis un fan de choses comme std::map<std::string, int (Handler::*)(void)>, ce qui me permet de créer une carte gestionnaire de méthodes de classe, mais YMMV.

EDIT: J'ai oublié de mentionner: l'autre bonne chose à propos d'avoir une carte de chaînes de méthodes est que vous pouvez modifier (généralement ajouter) à l'exécution.Par exemple, un analyseur peut modifier sa liste de mots-clés et leurs gestionnaires à l'exécution après avoir déterminé le type de fichier analysé.

+0

oui je pense que c'est la meilleure façon de faire le travail. –

+0

+1. Si le nombre d'instructions if/else dans une fonction est très grand, cela appelle généralement de telles solutions où nous pouvons coder et maintenir chaque branche d'exécution séparément sans maintenir de fonction gigantesque. – stinky472

+0

+1 pour mapper la chaîne aux méthodes. –

0

Trop de if déclaration sont odeur de code si vous pouvez les remplacer par un switch...case. Sinon, je ne vois pas le problème avec l'utilisation if.

Peut-être avez-vous utilisé plus de programmation événementielle en C#, alors que votre code C++ est plus séquentiel?

1

Ce n'est pas quelque chose que j'ai remarqué; J'ai fait 10 ans de C++ et 4 ans de C# aussi! Sûrement le nombre de si se rapporte à la conception de votre code plutôt que d'une différence entre C# et C++?

+0

C'est très probablement vrai, mais c'est juste quelque chose que j'ai remarqué, mais je peux me tromper. –

+1

J'ai vu des systèmes d'exécution de commandes naïvement codés en C d'une manière telle qu'il y avait plusieurs centaines ifs/elses vérifiant chaque chaîne de commande possible dans une seule fonction. – stinky472

+0

Peut-être que c'est à la différence dans la façon dont vous concevez des applications C++ par rapport à C#. Juste une pensée - je sais que mon style a changé au fil des ans.Je vais devoir garder un œil pour voir s'il y a une différence notable entre les deux langues sur les applications sur lesquelles je travaille en ce moment. – JLWarlow

1

Pour vous débarrasser des expressions conditionnelles dans les deux langues, vous pouvez considérer le Inversion of Control pattern. Il a l'effet secondaire de diminuer ceux-ci.

1

Basé sur la nature de 'bla' et 'blo' vous pouvez toujours essayer d'utiliser un std :: map, avec les chaînes comme clés.

0

Il existe de meilleurs moyens pour implémenter un analyseur de chaînes qu'un ensemble infini d'instructions if (strcmp...).

Une approche pourrait être une carte entre des chaînes et des pointeurs de fonction ou des objets de foncteurs.

Une autre conception pourrait impliquer un modèle de chaîne de responsabilité où la chaîne est passée à une chaîne d'objets qui décide s'ils ont une correspondance ou pour la transmettre.

Je ne suis pas au courant de quoi que ce soit à propos de C++ qui le rend plus vulnérable aux abus que tout autre langage.