En utilisant C ++ mais sans utiliser les fonctionnalités spécifiques du langage, devriez-vous passer en C?

16

Je développe un émulateur NES comme passe-temps, pendant mon temps libre. J'utilise C ++ parce que c'est le langage que j'utilise le plus, que je connais le plus et que j'aime le plus.

Mais maintenant que j'ai fait quelques progrès dans le projet, je me rends compte que je n'utilise pas presque toutes les fonctionnalités spécifiques de C ++, et j'aurais pu le faire en C simple et obtenir le même résultat. Je n'utilise pas de modèles, surcharge d'opérateur, polymorphisme, héritage. Alors que diriez-vous? dois-je rester en C ++ ou le réécrire en C?

Je ne ferai pas cela pour gagner en performances, cela pourrait venir comme un effet secondaire, mais l'idée est pourquoi devrais-je utiliser C ++ si je n'en ai pas besoin?

Les seules fonctionnalités de C ++ que j'utilise sont des classes pour encapsuler des données et des méthodes, mais cela peut aussi être fait avec des structures et des fonctions, j'utilise new et delete, mais pourrait aussi bien utiliser malloc et free, et je suis en utilisant l'héritage uniquement pour les rappels, ce qui pourrait être réalisé avec des pointeurs vers des fonctions.

Rappelez-vous, c'est un projet de loisir, je n'ai pas de délais, donc le temps supplémentaire et le travail qui nécessiteraient une réécriture ne sont pas un problème, pourraient aussi être amusants. Donc, la question est C ou C ++?

Petruza
la source
3
Il me semble que vous vous êtes déjà répondu: pourquoi utiliser C ++ si vous n'avez besoin que de C? Il existe de nombreuses situations dans lesquelles C est parfaitement OK.
Giorgio
3
@Giorgio: Et ils s'évaporent tous après les soixante premières secondes et vous devez conserver votre code.
DeadMG
7
I use C++ because is the language I use mostly, know mostly and like mostly.Et c'est la réponse à votre question. Vous ne devez changer de langue au milieu du projet qu'en cas de problème que votre langue actuelle ne peut pas résoudre. I don't use templates, operator overloading, polymorphism, inheritance.Il serait beaucoup plus utile d'apprendre et d'utiliser les concepts que de passer au C. Comme il s'agit d'un projet de loisir, pourquoi ne pas utiliser quelques éléments que vous n'avez pas utilisés auparavant? Vous pouvez toujours démarrer un autre projet en C et apprendre la langue, mais pour votre projet actuel, cela n'a pas de sens de changer.
yannis
4
Je n'utilise pas non plus 100% d'une langue dans chaque projet que j'écris. Vous connaissez mieux le C ++, vous trouverez peut-être de bonnes raisons d'utiliser des fonctionnalités pour lesquelles vous n'avez jamais trouvé d'utilisation auparavant. Vous pouvez commencer à traiter C ++ comme beaucoup plus sûr C, une fois que vous commencez à utiliser la substance de la bibliothèque standard et des constructions de stimuler le souhaitez std::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::map, etc. Pour les fonctions de rappel, regard sur l'utilisation de foncteurs, et en C ++ 11, vous peut également commencer à utiliser des choses comme les fonctions lambda.
wkl
3
@Giorgio: Oui. Rouler la liste chaînée infinie est lié à produire des erreurs inutiles.
DeadMG

Réponses:

40

Vous ne l' utilisez pas maintenant, mais la prochaine fois que vous fuite de mémoire ou d' obtenir une double suppression, vous serez supplient de revenir std::vector<T>, std::unique_ptr<T, Del>et std::shared_ptr<T>qui peut résoudre ces problèmes easily- presque trivialement. C'est ce qui arrive à tous ceux qui utilisent C sur C ++, et les plus intelligents n'attendent tout simplement pas que les bogues apparaissent avant de passer.

Le code qui utilise newet deletedirectement n'appartient pas vraiment en C ++, il appartient à ce genre de demi-maison que nous appelons "C avec classes". C'est là que le langage était vers 1985. Ce n'est pas particulièrement similaire au C ++, vers 2011. Selon toute vraisemblance, partout où vous avez appris le C ++ ne l'enseignait tout simplement pas très bien - quelque chose qui est malheureusement assez courant - et avec une meilleure éducation, vous le feriez trouver l'utilisation de ces fonctionnalités.

Plus précisément, comme je l'ai indiqué ci-dessus, les structures de données génériques de C ++ et les classes de gestion des ressources sont tout simplement massivement supérieures à tout ce que C a à offrir. Si vous voulez un tableau alloué dynamiquement, alors utilisez std::vector<T>. C'est un cas d'utilisation assez courant. Si vous ne les utilisez pas, votre code présente un énorme risque d'erreur inutilement, en particulier en ce qui concerne la gestion des ressources. C ++ peut garantir la sécurité et la réutilisation du code d'une manière que C ne peut jamais toucher.

Cependant, je pense que vous attendez peut-être aussi trop. L'écriture de modèles et de surcharges d'opérateurs n'est pas courante pour les consommateurs de bibliothèques. Si votre code utilise std::vector<T>, vous n'avez pas besoin d' écrire un modèle pour y arriver. Si votre code utilise std::string, personne ne vous oblige à surcharger vos opérateurs. Vous n'avez qu'à faire ces choses pour écrire std::vector<T> et std::string- mais vous pouvez toujours en profiter pleinement.

Le polymorphisme / héritage n'a également qu'un cas d'utilisation spécifique. Si votre code ne vous oblige pas à écrire de modèles ou à utiliser des fonctions virtuelles, ce n'est pas le cas, et il existe des programmes ou des segments de programmes où vous n'avez pas besoin d'écrire vos propres modèles.

En outre, il n'y a aucun gain de performances en C sur C ++.

DeadMG
la source
1
@Giorgio: make_sharedexiste, et vous pouvez écrire un make_uniquemodèle trivial qui fait le même travail. C'est plus sûr.
DeadMG
4
Très bonne réponse. Clou sur la tête. C ++ est le plus précieux pour ces petites bibliothèques que nous devrions toujours utiliser.
Andres Jaan Tack
2
@Giorgio: Ce n'est pas sûr car lors de l'appel de plusieurs arguments comme celui-ci, vous pouvez obtenir une fuite de mémoire en cas d'exception, et make_sharedc'est plus efficace. Seules les fonctions d'usine peuvent offrir une sécurité d'exception garantie.
DeadMG
6
@ tp1: WTF? En anglais s'il vous plait.
DeadMG
2
@Lohoris Vous n'avez pas besoin d'une citation pour le bon sens. De quelle manière C devrait-il être plus performant que C ++?
Chris dit de réintégrer Monica
7

Même si vous n'utilisez pas de fonctionnalités spécifiques à C ++, un compilateur C ++ détectera plus de problèmes qu'un C en raison du système de type plus strict de C ++.

Nemanja Trifunovic
la source
6

Je le regarderais dans l'autre sens. Allez-vous gagner quelque chose en réécrivant le code en C? Même sur un projet purement amateur, il y a un coût associé à une réécriture comme ça. S'il n'y a rien d'autre, il y a ce que je suppose être appelé coût d'opportunité - c'est-à-dire les autres choses que vous auriez pu faire pendant cette période si vous n'aviez pas perdu votre temps à le réécrire en C.

Conclusion: à moins que vous ne pensiez que le code est vraiment susceptible d'être utilisé dans un environnement où l'accès à C ++ est vraiment limité (ou inexistant), ce serait au mieux une perte de temps inutile. Au moins selon mon expérience, cela va généralement bien au-delà de cela très rapidement - en repensant au code que j'ai écrit en C ++ qui devait être converti en C, je me souviens assez clairement que même dans quelques cas où cela semblait cela devrait être trivial, j'utilisais beaucoup plus de fonctionnalités spécifiques au C ++ que je ne l'avais initialement imaginé. Pour avoir beaucoup d'espoir d'être utile, vous devez à peu près cibler C89 / 90, auquel cas vous vous souvenez rapidement de choses comme devoir définir toutes les variables au début d'un bloc au lieu de leur emplacement réel utilisé.

En bref, à moins d'être certain que la réécriture en C fournira un réel avantage, il y a presque inévitablement beaucoup de meilleures choses à faire.

Jerry Coffin
la source
+1 Il y a quelque temps, j'ai dû écrire une bibliothèque à utiliser dans un autre projet C et j'ai pensé que c'était une bonne idée de l'implémenter également en C, mec quel idiot stupide j'étais à l'époque.
Chris dit de rétablir Monica
1

Comme réponse plus générale:

Ne passez pas au C ++ simplement parce que vous utilisez certaines de ses fonctionnalités plus uniques. Un jour, vous aurez peut-être besoin de ces fonctionnalités et vous frapperez la tête parce que vous utilisez C.

Dynamique
la source
1

Pour le développement amateur, j'envisagerais de revenir au simple C. Les langages C. C et C sont plus susceptibles d'être pris en charge sur de minuscules modules de développement amateur.

La plupart des réponses peuvent provenir de types de logiciels professionnels. En tant qu'amateur, vous ne coderez pas en continu ou à plein temps. Considérez donc dans quelle langue vous êtes le plus susceptible de vous souvenir ou d'oublier les caprices, si vous déposez votre projet pendant un an, puis revenez et essayez de lire votre code après avoir rouillé dans le codage. C ++, ayant un ensemble de fonctionnalités plus riche, peut prendre plus ou moins de temps à réacquérir, selon votre style de codage.

hotpaw2
la source
1

Il n'est pas facile de répondre à vos questions, car nous ne savons pas si vous travaillez sur le projet pour améliorer vos compétences spécifiques au langage (C vs C ++) ou pour améliorer d'autres compétences en programmation (conception, résolution de problèmes, etc.).

"Les seules fonctionnalités de C ++ que j'utilise sont des classes pour encapsuler des données et des méthodes, mais cela peut aussi être fait avec des structures et des fonctions". Ce n'est pas vrai. structsen C ne prend pas en charge l'encapsulation et ne peut pas contenir de fonctions (méthodes) - du moins pas sans utiliser des techniques telles que des pointeurs vers des fonctions. De plus, les fonctions en C sont plus faibles car elles ne peuvent pas être surchargées.

"J'utilise new et delete, mais je pourrais aussi bien utiliser malloc et free, et j'utilise l'héritage juste pour les rappels, ce qui pourrait être réalisé avec des pointeurs vers des fonctions.". Comme mentionné précédemment, l'utilisation directe newet deleteen C ++ n'est pas encouragée. De plus, l'héritage à mon humble avis (et le GoF) dans la POO doit être préféré à la composition uniquement lorsqu'un polymorphisme est requis. Et je ne pense pas qu'il soit trivial de réaliser le polymorphisme (liaison tardive) en C en utilisant des pointeurs vers des fonctions.

En dehors de cela, je n'essaierai pas de vous convaincre que C ++ est "meilleur" que C car c'est une question de préférence et cela dépend toujours du problème que vous essayez de résoudre (l'utilisation des fonctionnalités de POO pour développer votre émulateur NES peut être une bonne idée).

sakisk
la source
1
structsen C peut, en fait, être utilisé pour encapsuler des méthodes. Vous créez simplement une structure de pointeurs de fonction et les initialisez pour pointer vers les fonctions souhaitées. Jetez un œil à lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 pour un exemple.
Robert Martin
C'est vrai. Merci pour le commentaire, j'ai étendu la réponse.
sakisk
Agréable. Encore une chose: les fonctions en C peuvent être surchargées (pensez printf), mais ce faisant, vous perdez toute vérification de type. Il n'y a aucun moyen d'avoir un ensemble fini de déclarations acceptables: c'est soit 1 (et vous obtenez la vérification de type) ou "plusieurs" (et perdez toute vérification de type, au grand risque personnel). Comme avec la plupart des choses en C, c'est possible mais souvent inconfortable.
Robert Martin
Les pointeurs vers les fonctions sont une technique C avancée? Vraiment?
Donal Fellows
@DonalFellows Vous avez raison, j'ai exagéré. Suppression avancée ... :)
sakisk
0

Je suis très débutant, voici donc mes 2 bits.

J'apprends le C et le C ++ sur Wibit.net avec de jolis tutoriels vidéo de base, peut-être qu'ils peuvent vous aider beaucoup à prendre un aperçu de la "situation" (pas une annonce!)

Je vous conseille de passer au C, juste pour apprendre, comme vous êtes amateur, ce sera un plaisir, pas un problème.

Je conseille plus. Faites-le dans les deux langues. Comparez la manière et les solutions que vous trouverez et utiliserez. Je suis sûr que ce ne sera pas "aussi facile" que ce à quoi vous vous attendez ... mais vous apprendrez beaucoup!

H_7
la source
1
Merci beaucoup, mais je n'apprends pas, je connais déjà le C et le C ++, je demande lequel utiliser pour ce projet spécifique.
Petruza
oups, mon temps pour apprendre! = P
H_7
1
De plus, je conseillerais qu'au lieu de tutoriels vidéo, vous obtenez les livres de Kernigan et Stroustrup, un bel IDE (Visual Studio, Eclipse, Xcode) et apprenez en codant les exemples, les essais et les erreurs et en recourant à stackoverflow.
Petruza
-1

Voici les avantages et les inconvénients de C ++ par rapport à C:

  1. Le passage à C faciliterait le maintien du sous-ensemble C ++ choisi, car le compilateur donnerait alors une erreur lorsque vous en sortiriez. Si le problème principal est de rester dans le sous-ensemble décidé, cette alternative doit être choisie. (pourquoi n'avons-nous pas le support du compilateur pour cela?)
  2. Une fois que vous pouvez rester dans le sous-ensemble de fonctionnalités c ++ choisi, la prochaine chose est d'essayer de changer le sous-ensemble pour vous débarrasser des mauvaises conventions qui cassent le code. Cela nécessite l'utilisation de c ++ entier.
  3. Une fois que vous avez à la fois «rester dans le sous-ensemble» et «c'est un bon sous-ensemble», sortez des fonctionnalités c ++ et commencez à réfléchir aux exigences.
tp1
la source