Devrions-nous éviter les fonctionnalités de langage que C ++ possède, mais pas Java?

110

Supposons que je suis limité à l’utilisation de C ++ par l’environnement du projet. Est-il bon d'empêcher l'utilisation de certaines fonctionnalités du langage que C ++ possède mais que Java n'a pas (par exemple: héritage multiple, surcharge d'opérateur)?

Je pense que les raisons sont:

  1. Comme Java est plus récent que C ++, si Java ne fournit pas une fonctionnalité dont C ++ dispose, cela signifie que la fonctionnalité n'est pas bonne, nous devons donc éviter de l'utiliser.
  2. Le code C ++ avec des fonctionnalités spécifiques à C ++ (par exemple, les fonctions ami, l'héritage multiple) ne peut être maintenu ou révisé que par les programmeurs C ++, mais si nous écrivons simplement C ++ comme Java (sans fonctionnalité spécifique au langage C ++), le code peut être maintenu ou révisé par les deux. Programmeurs C ++ et Java.
  3. On vous demandera peut-être de convertir le code en Java un jour.
  4. Le code sans fonctionnalités spécifiques à C ++ est généralement plus facile à gérer
  5. Chaque fonctionnalité spécifique au langage C ++ (par exemple: l'héritage multiple) devrait avoir des alternatives à implémenter en Java. Si ce n'est pas le cas, cela signifie que le modèle de conception ou l'architecture du code est problématique.

Est-ce vrai?

ggrr
la source
7
Si vous regardez vos suggestions, vous parlez de créer une norme de codage. Le fait que vous créez et respectiez une norme est en fait ce qui augmentera la facilité de maintenance.
Brandin
63
Le code Java devrait-il également être limité aux fonctionnalités, également présentes dans le langage C ++? Donc, n'utilisez pas, par exemple, Java volatile, l'accès aux membres d'une classe privée par le paquet, la réflexion / l'introspection, enfin-les blocs, les exceptions vérifiées, etc. Toute la question n'a pas beaucoup de sens ... C ++ et Java sont superficiellement similaires, mais finalement des langages très différents.
Hyde
5
Comment les langues évolueront-elles si les gens ne veulent pas utiliser les nouvelles fonctionnalités? Les nouvelles fonctionnalités ont pour but de vous simplifier la vie en résolvant les problèmes courants. Si les utilisateurs n'utilisent pas les nouvelles fonctionnalités, personne ne les incite à les implémenter.
Matthieu
72
Si vous voulez Java, utilisez Java. Si vous utilisez C ++, utilisez C ++, et non une horrible imitation tordue de Java avec la syntaxe C ++. Utiliser C ++ mais vous limiter aux fonctionnalités de Java vous donne le pire des deux mondes.
Jerry Coffin
11
Vous seriez surpris par la rapidité avec laquelle les différences vous mordront (et durement ). SomeObject a = previousObject;fait des choses très différentes en Java et en C ++. En Java, il copie une référence, tandis qu'en C ++, il copie l'objet. En Java, les modifications apportées aaffectent également l'objet précédent. En C ++, vous avez deux objets distincts.
Clockwork-Muse

Réponses:

307

Non, c’est lamentablement et terriblement mal avisé.

  • Les fonctionnalités Java ne sont pas meilleures que les fonctionnalités C ++, en particulier dans le vide.
  • Si vos programmeurs ne savent pas comment utiliser une fonctionnalité, formez ou embauchez de meilleurs développeurs; limiter vos développeurs au plus mauvais de votre équipe est un moyen rapide et facile de perdre vos bons développeurs.
  • YAGNI . Résolvez votre problème actuel aujourd'hui, pas le fantôme d'un problème futur.
Telastyn
la source
6
On a récemment posé une question à propos de la révision du code par les développeurs dans un langage qu’ils n’écrivent pas normalement. Je pense que la sagesse s’applique ici: un bon développeur repérera de nombreuses erreurs fondamentales dans presque toutes les langues, mais chaque langue a tellement de gotchyas qu’un bénéfice maximal est obtenu lorsque les développeurs in-language font la révision. Cela est même vrai si votre C ++ est "Fonctionnalités Java uniquement".
CorsiKa
5
+1 En plus de votre deuxième point. Le PO devrait prendre le temps de se renseigner sur les "meilleures pratiques C ++" pour décider des fonctionnalités à utiliser. Mes dernières informations sur le C ++ sont que les fonctions d'amis et l' héritage multiple sont considérés comme des mauvaises pratiques . Des choses comme les modèles et la surcharge d'opérateur sont des bonnes pratiques IMHO si vous les utilisez judicieusement.
some_coder
4
@some_coder: Tout est une question de savoir quand et où. Lorsque je fais de la programmation basée sur des règles, je hérite des classes de règles (éventuellement multiples) pour étendre la structure de ma classe hôte avec les membres dont ces classes ont besoin pour fonctionner. C'est juste comment ça marche. En outre, operator<<( ostream &, T const & )est généralement mis en œuvre via friend. Voilà le problème avec les déclarations générales sur ce qui constitue une bonne fonctionnalité linguistique et une mauvaise: elles sont de bons conseils, sauf lorsqu'elles ne le sont pas ...
DevSolar
142

Ce n'est pas parce que la syntaxe semble similaire à première vue que les deux langages sont compatibles.

1, 4 et 5 sont vraiment la même question:

Maintenant, je ne suis pas un fan de C ++, mais dire que "Code sans fonctionnalités spécifiques à C ++ est généralement plus facile à gérer" est tout simplement ridicule - croyez-vous vraiment que Java a tout bon, et a pris toutes les bonnes fonctionnalités tout en ignorant toutes les mauvaises? Croyez-vous vraiment qu'il y a quelque chose qui est universellement une fonctionnalité "mauvaise" ou "bonne"? Si c'est le cas, pourquoi n'avons-nous pas une langue purement bonne? Et non, Java n’est certainement pas ce langage. Est-ce que cela signifie que Java et C ++ sont inutiles? Bien sûr que non.

Que se passe-t-il si vos dirigeants décident que vous allez porter en C #, plutôt qu'en Java? Non seulement C # soutien aux opérateurs majeur, mais il est aussi la valeur par défaut - si vous allez obliger les gens à utiliser , par exemple au obj.Equals(obj2)lieu de obj == obj2, les gens vont faire des erreurs tout le temps. Même si vous vous en tenez uniquement aux caractéristiques communes des deux langues, il existe des attentes différentes , une culture différente. Si vous faites quelque chose comme if (myField == null)en C ++, les gens verront que vous êtes novice immédiatement. Si vous utilisez if (null == myField)en C #, les gens verront que vous n'êtes pas encore vraiment natif en C # - les raisons pour lesquelles les développeurs C ont appris à utiliser la variante "inversée" n'existent plus en C #.

En utilisant votre logique, nous devrions nous en tenir à du code machine, à un assemblage ou à un COBOL, car pourquoi changer en quelque chose comme Pascal, cela ajoute-t-il de nouvelles fonctionnalités que vos programmeurs devront apprendre? Pourquoi utiliserions-nous quelque chose comme SQL, alors qu'il n'y a même pas de boucles ? Pourquoi utiliserions-nous autre chose que SQL, alors que SQL n'a pas de boucles et que X en a ?

Le code C ++ ne peut certainement pas être maintenu par les programmeurs Java. Je ne comprends pas où vous avez eu cette idée. Que reste-t-il exactement lorsque vous limitez le C ++ aux seules fonctionnalités qui fonctionnent exactement comme en Java? Vous n'allez même pas recevoir d'appels de méthode, pas même d' appels de fonction . Encore une fois, ce n'est pas parce que les deux langages utilisent des accolades que les langues sont interchangeables.

La conversion de code C ++ de type Java sera extrêmement sujette aux erreurs, peu importe ce que vous ferez. Il y a trop de différences. Si vous souhaitez réécrire votre application dans une autre langue, réfléchissez à des moyens raisonnables de tout modéliser, afin de pouvoir remplacer les pièces sans casser le tout. Mais à la fin, YAGNI - peu importe ce que vous ferez, il en coûtera beaucoup pour que votre code soit "prêt à être converti en Java". Ce temps est très probablement mieux dépensé pour ajouter ou améliorer vos fonctionnalités.

Nous utilisons des langages différents car ils nous fournissent un ensemble d’outils différents pour résoudre les problèmes. Si vous avez besoin d'exécutables fonctionnant "partout", utilisez Java. Si vous voulez un code qui compile "partout", C ++ fonctionne bien. Si vous voulez un code facile à comprendre et à analyser, utilisez LISP ou autre. Mais je peux vous dire une chose: écrire du code dans une langue comme si vous l'écriviez dans une autre est toujours une erreur et vous allez en souffrir. Sans parler du fait que lorsque vous embauchez un responsable C ++, il s'exécutera à la seconde où il verra ce code "compatible Java-ish". Et ... le gars de Java va faire la même chose. Vous savez, même en "sachant" à la fois en C ++ et en Java, je courrais comme l'enfer :)

En fait, je devais travailler sur du code C (clair) écrit par un développeur Pascal qui semblait penser comme vous. Il avait l'habitude #definede redéfinir C pour qu'il ressemble davantage à Pascal, avec des choses comme "BEGIN se traduit par {". Le résultat était plutôt prévisible - un code que ni les développeurs C ni Pascal ne peuvent comprendre, et plein de bogues qui résultaient de la "abstraction" fuyante de Pascal au-dessus de C. Et Pascal et C sont presque identiques du point de vue actuel. Même aller en C <-> C ++ est beaucoup plus d'une différence, et c'est encore une cacahuète à quelque chose comme C ++ <-> Java.

Luaan
la source
9
"Si vous voulez un code facile à comprendre et à analyser, utilisez LISP ou ce que vous voulez." Je ne serais pas d'accord avec ça. Lisp est simple à analyser, mais justement à cause de cela - car il a été créé à une époque où la connaissance des analyseurs et les principes qui les sous-tendent étaient efficaces pour en construire encore, et ils ont donc décidé de procéder avec le plus ridiculement simpliste cela pourrait éventuellement fonctionner - vous n’obtenez pas beaucoup des avantages syntaxiques des langues modernes. Il est donc facile à analyser, mais pas du tout facile à comprendre . Il y a une raison pour laquelle les gens l'appellent "Perdu dans des parenthèses superflues".
Mason Wheeler
9
@MasonWheeler C'est une question de goût - les programmeurs C l'appelaient ainsi, pas les utilisateurs LISP: P. Comptez les parenthèses - il y en a à peu près autant que dans votre programme C ++ typique. La vraie différence est leur position ( myFunc()par rapport à (myFunc)), et cela a une très bonne raison. Les langages basés sur LISP sont toujours très populaires, en particulier auprès des maths / physics. Le principal est que les langages LISPy sont très peu familiers des programmeurs modernes de style C - mais ce n’est pas une raison pour l’ignorer. Scheme, Clojure et, dans une certaine mesure, les langages basés sur ML (OCaml, F # ...) sont vraiment très LISPES.
Luaan
4
@Luaan Je peux vous dire avec certitude que LISP n'est PAS populaire en physique. Les deux langues dominantes dans ce domaine sont le Fortran et le C ++. FORTRAN est «populaire» car de nombreux codes anciens y étaient écrits, mais presque tous les nouveaux programmes sont écrits en C ++. En tant que physicien chercheur, je n'ai jamais rencontré ni entendu parler d'un programme LISP. Pour ne pas dire qu'ils n'existent pas, mais les langues ne sont certainement pas populaires .
James Matta
4
@Luaan Nous pouvons ou non avoir besoin de plus de développeurs de logiciels. Nous n'avons certainement pas besoin de plus de diplômés en CS. C'est comme dire "nous avons besoin de plus d'ingénieurs en structure, donc nous avons besoin de plus de diplômés en physique théorique".
Miles Rout
4
@ user1717828 Il est d'éviter les effets de délicieux mistyping if (myField == null)que if (myField = null), qui compilera très bien C / C ++, mais probablement pas faire ce que vous aviez l' intention. D'autre part, if (null = myField)jettera une erreur, car vous ne pouvez pas affecter une constante.
Wlerin
94

Je vais répondre à vos questions dans l'ordre.

  1. Si Java ne fournit pas une fonctionnalité dont dispose le C ++, cela signifie que la fonctionnalité n'est pas bonne, nous devons donc empêcher son utilisation.

Oui, toute fonctionnalité non présente en Java est un anathème sur le disque dur. Il doit être gravé à partir de votre base de code. Ceux qui n'obéissent pas seront rejoués, leur âme apaisée pour apaiser les dieux du RAID.

  1. Le code C ++ avec des fonctionnalités spécifiques à C ++ (par exemple, les fonctions ami, l'héritage multiple) ne peut être maintenu ou révisé que par les programmeurs C ++, mais si nous écrivons simplement C ++ comme Java (sans fonctionnalité spécifique au langage C ++), le code peut être maintenu ou révisé par les deux. Programmeurs C ++ et Java.

En cas de doute, écrivez le code du membre le moins compétent de votre équipe. Le code est lu beaucoup plus souvent qu'il n'a été écrit et un code aussi intelligent que vous pouvez écrire est trop intelligent pour être lu. Les révisions de code que votre personnel à la réception ne comprendra pas devraient être rejetées. Pour vous aider, apprenez-leur à programmer Visual Basic 2.0 au cours du week-end, puis émulez leur style de codage dans la langue que vous utilisez.

  1. On vous demandera peut-être de convertir le code en Java un jour.

Vrai! Mais pourquoi s'arrêter à Java? Vous pouvez être invité à convertir le code en base, en assembleur et / ou en perl un jour. Comme il existe des interprètes Perl dans toutes les langues, écrivez simplement votre programme sous la forme d'une longue chaîne perl et associez-y des arguments dans la langue de votre choix.

Maintenant, lorsque vous avez besoin de changer de langue, réécrivez simplement le code qui enveloppe la chaîne Perl.

  1. Le code sans fonctionnalités spécifiques à C ++ est généralement plus facile à gérer

Il est vrai que le code utilisant moins de fonctionnalités est plus facile à gérer. Et comme toutes les langues sont équivalentes à une machine de Turing, et qu'une machine de Turing possède le moins de fonctionnalités qu'un langage de programmation, demandez à l'interprète perl ci-dessus d'exécuter une machine de Turing (bande et tout) qui résout votre problème.

  1. Chaque fonctionnalité spécifique au langage C ++ (par exemple: l'héritage multiple) devrait avoir des alternatives à implémenter en Java. Si ce n'est pas le cas, cela signifie que le modèle de conception ou l'architecture du code est problématique.

Les fonctionnalités spécifiques au langage C ++ ont en réalité une utilisation précieuse. Comme ils ne sont pas Java, ils sont anathèmes et ceux qui les utilisent peuvent être considérés comme des hérétiques. Si C ++ n'avait pas ces fonctionnalités de langage, vous ne pourriez pas trouver celles que vous devez sacrifier. Les fonctionnalités du langage C ++ résolvent les problèmes!


Regardez, C ++ et Java ont un ensemble de capacités différent. La programmation à l'intersection de C ++ et de Java produit un code qui a jeté la plupart des avantages des deux langages.

Java a été développé partiellement en réaction à certains abus des fonctionnalités C ++. Cela ne veut pas dire que la réaction était justifiée, surtout des années après que les traits aient mûri.

Vous pouvez faire des choses horribles avec la surcharge de l'opérateur; mais aucune langue ne peut empêcher un code horrible d'être écrit dans la langue, à moins que cela n'empêche tout le code d'être écrit dans la langue.

Et vous pouvez également faire des choses très élégantes avec la surcharge de l'opérateur. Des choses simples, comme un nombre complexe ou une classe matricielle qui fonctionne comme un nombre complexe ou une matrice.

La prudence concernant l'utilisation de fonctionnalités C ++ non disponibles en Java doit être considérée avec prudence. Ce n'est pas parce que votre groupe actuel de développeurs, au niveau de compétences actuel, ne comprend pas qu'une fonctionnalité ne doit jamais être utilisée; En même temps, le fait d’utiliser une fonctionnalité ne signifie pas que vous devriez le faire. Cependant, dans un magasin Java-lourd, les chances sont que la résistance sera plus forte qu'elle ne devrait l'être contre les fonctionnalités non-Java.

La conversion du code entre les langues s’effectue mieux avec une réécriture, quelle que soit leur structure. Toute tentative de le faire sans une telle réécriture échouera lamentablement.

De nombreuses fonctionnalités spécifiques à C ++ sont des merveilles pour la maintenance. Le type effacement (comme std::function) vous permet de découpler les hiérarchies, ce qui réduit les dépendances. Les pointeurs intelligents et les durées de vie déterministes et RAII réduisent les surprises au moment de l'exécution et éloignent les ressources des ressources. De lourdes vérifications de types statiques signifient que la compilation du code échoue, au lieu de ne pas fonctionner. Les mixages réduisent la duplication de code. ADL permet une extension indépendante ad-hoc des interfaces entre les hiérarchies de types. Lambda vous permet d'écrire du code à côté de l'endroit où il est utilisé. Le transfert et le déplacement réduisent le nombre de copies et optimisent l'efficacité de la programmation de style fonctionnel (sans effets secondaires). La surcharge des opérateurs réduit le bruit de ligne et rend le code plus proche des calculs qu’il modélise.

Attention à la fosse de Turing Tar. Vous pouvez tout implémenter dans n'importe quelle langue (y compris une machine de Turing avec bande crue), mais cela ne veut pas dire que vous devriez le faire . Émuler des fonctionnalités C ++ à l'aide de constructions Java-esque en C ++ est une idée horrible. il en résultera un code inaccessible que personne ne peut lire ni comprendre.

Vous pouvez vous inspirer des conceptions Java et les transférer en C ++. Je suis un grand fan des fonctionnalités du langage Python et de leur implémentation en C ++, parce que j'aime la syntaxe. Mais cela ne signifie pas que j'écrive mes méthodes de classe en tant que méthodes statiques prenant un self explicite, puis écris un wrapper qui lui transmet l'appel de méthode non statique.

Le C ++ moderne ne ressemble pas tellement au langage Java imité et rejeté. Ne vous laissez pas enfermer par les caractéristiques d'une langue. il n'y a pas "une seule langue vraie". En savoir plus sur les nouvelles langues et leurs caractéristiques, et absorber leur caractère distinctif.

Yakk
la source
1
-1, long et incertain.
Djechlin
4
-1 argumentatif, argument homme de paille
utilisateur949300 le
28
+1, déconstruction appropriée des questions posées et j'ai ri :)
cat
11
+1 Hilarante mais garde le point. Très clair pour les gens qui le lisent réellement.
Luis Masuelli
14
"La programmation à l'intersection de C ++ et de Java produit un code qui a jeté la plupart des avantages des deux langages." Mettre le doigt dessus! +1
Ajedi32
56

Je vais juste répondre à vos raisons:

  1. Je ne comprends pas comment vous en êtes arrivé à cette conclusion. Différentes langues ont des caractéristiques différentes. Dépend de la portée, de l'architecture du langage, parfois des préférences des créateurs et de nombreuses autres raisons. Certaines caractéristiques d'une langue peuvent être mauvaises, mais votre généralisation est tout simplement fausse à mon humble avis.
  2. Écrire en C ++, tout comme Java, peut conduire à un code pire. Par exemple, de nos jours, avec C ++ 11, j'évite d'utiliser new / delete, mais j'utilise des pointeurs partagés. Dans votre scénario, je me fierais uniquement à nouveau / supprimer. Si vos programmeurs ne comprennent que Java, formez-les ou engagez-en de meilleurs.
  3. Est-ce que cela va probablement arriver? Pourquoi n'écris-tu pas en Java en premier lieu? Je pense que réécrire des programmes à partir de zéro dans une nouvelle langue est généralement une mauvaise idée et que vous auriez besoin d'une très bonne justification pour un tel risque.
  4. Ceci est juste une hypothèse.
  5. Dépend IMHO fortement sur votre scénario ou cas d'utilisation.
Simon
la source
27
Et les programmeurs Java n'utilisent pas non deleteplus.
Paŭlo Ebermann
8
J'ai dû réparer des fuites de mémoire causées par des programmeurs Java ignorants delete. D'après mes souvenirs, dans au moins un de ces cas, l'allocation dynamique ( new) n'était pas nécessaire non plus.
Ethan Kaminski
16
@EthanKaminski Oui, c'est comme ça que vous pouvez facilement repérer un débutant en C ++, en particulier quelqu'un qui vient d'un environnement Java ou similaire. Arrêtez d'utiliser nouveau pour tout, bon sang!
Luaan
1
@ PaŭloEbermann Oui, même pire.
Simon le
1
"Dans votre scénario, je ne m'appuierais que sur new / delete" - drôle, j'aurais pensé qu'un idiome C ++ "Java (similaire) ne comporte que des fonctionnalités" serait exclusivement utilisé make_shared.
Kyle Strand
26

Java possède des fonctionnalités que C ++ n’a pas, comme un récupérateur de place intégré, rapide et fiable, une hiérarchie d’objets à racine unique et une introspection puissante.

Les autres fonctionnalités de Java sont conçues pour fonctionner avec les fonctionnalités exclusives à Java. De nombreuses omissions de fonctionnalités C ++ par Java sont possibles, car les nouvelles fonctionnalités compensent ce manque. Par exemple, Java n’a pas d’objets alloués à la pile avec des destructeurs déterministes, mais a finalement des blocs (et des ressources d’essai depuis Java 7) et le garbage collector pour compenser ce manque.

C ++ n'a finalement pas de blocs ou de garbage collection. Si vous n'utilisez pas de destructeurs car ils n'existent pas en Java (je ne compte pas les finaliseurs), vous êtes au niveau C de la gestion des ressources (c.-à-d. Tout manuel), sauf que vous ne pouvez même pas grouper votre nettoyage. dans un bloc de nettoyage que vous devez, car Java ne l’a pas non plus. Pensez-vous vraiment que cela améliore la maintenabilité?

Java a une hiérarchie d'objets globale dans laquelle chaque classe dérive finalement d'Object, et les quelques types primitifs peuvent également être automatiquement encadrés dans de telles classes. Cela permet d’écrire des conteneurs d’objets une seule fois, pour conserver les pointeurs sur Object. Java 5 a introduit les génériques, qui suppriment les moulages que nécessitent de tels conteneurs, mais compilent toujours à peu près le même code.

C ++ n'a pas une telle hiérarchie. Pour faciliter l'écriture de conteneurs qui fonctionnent pour plusieurs types, vous utilisez des modèles, qui sont des plans instanciés par le compilateur selon les besoins pour différents types. Allez-vous interdire l’utilisation de modèles (et de macros) et choisir la méthode C pour écrire le même code de conteneur encore et encore pour différents types ou pour utiliser des pointeurs vides? (Attendez, Java n’a pas de pointeur vide)! Êtes-vous sûr que cela augmenterait la maintenabilité?

Une langue décente a une multitude de fonctionnalités conçues pour fonctionner ensemble. En interdisant les fonctionnalités du langage A parce que le langage B ne les possède pas, vous paralysez le langage A, car vous n’ajoutez pas en même temps des fonctionnalités de B qui font de B un tout cohérent.

Cela ne veut pas dire que vous ne devez pas restreindre les fonctionnalités autorisées de C ++. Le C ++ est un langage grand, développé historiquement, qui permet au programmeur de faire ce qu'il veut au-dessus de la sécurité et de la facilité d'utilisation, et toutes ses fonctionnalités, dans toute leur flexibilité, ne sont pas nécessaires pour construire de bons programmes. De nombreuses normes de codage limitent l'utilisation de certaines fonctionnalités. Par exemple, les directives de Google interdisent généralement l'héritage multiple, les modèles complexes et les exceptions (bien que ce dernier soit pour des raisons historiques). Mais aucune fonctionnalité n'est interdite "car Java ne l’a pas"; les fonctionnalités sont considérées uniquement dans le cadre de C ++.

Sebastian Redl
la source
27
Les vétérans chevronnés du C ++ rejettent généralement les directives de codage de Google. Le C ++ moderne est nettement meilleur car il utilise ces fonctionnalités. Oui, cela le rend encore plus différent.
Jan Hudec
17
Notez que C ++ n’a pas de bloc final, mais il a RAII, ce qui est bien meilleur dans la plupart des cas. Et, encore une fois, différent.
Jan Hudec
7
Java Objectest à peu près un void*pour la plupart des utilisations - Pourtant, beurk.
Quentin
1
Au-delà du choix des fonctionnalités, il y a la question du style et de l'idiome. Les programmes sont généralement plus faciles à lire et à entretenir s’ils utilisent les idiomes normaux pour la langue dans laquelle ils ont été écrits. Même si l'on pouvait écrire une partie d'un programme C ++ en utilisant uniquement des fonctionnalités de type Java, le résultat serait un étrange C ++ stilté.
Patricia Shanahan
2
Je préférerais invoquer cette réponse pour être sur la bonne voie ("ne le faites pas"), mais je ne supporte pas le principe de base selon lequel Java est en quelque sorte "plus avancé" que le C ++. C ++ n'a pas besoin d' un garbage collector ni d'une hiérarchie d'objets à racine unique, de la même manière que Java n'a pas besoin de ... euh ... désolé, je ne sais pas comment terminer la phrase, car les destructeurs déterministes de Java me manquent , et finallyn'est pas un remplacement pour eux. Les deux langues sont fondamentalement différentes.
DevSolar
25

J'ai débattu de la possibilité de publier une autre réponse alors que vous avez déjà un numéro qui atteint des conclusions qui semblent tout à fait raisonnables: votre idée est essentiellement une catastrophe imminente. Je pense cependant qu'ils n'ont pas réussi à indiquer certaines raisons extrêmement pertinentes derrière cette conclusion.

Les différences entre Java et C ++ sont beaucoup plus profondes que les détails sur lesquels vous semblez vous être concentré.

Par exemple, vous parlez d'interdire l'héritage multiple en C ++. Premièrement, je ferai remarquer que cela manque simplement le point. Java définit les "interfaces" comme des éléments distincts des "classes". Une classe hérite d'une seule autre classe, mais peut implémenter un nombre arbitraire d'interfaces.

C ++ ne sépare pas les deux concepts de cette façon. Le C ++ analogique le plus proche fournit une interface de mise en œuvre en Java est hérite d' une autre classe. En tant que tel, pour maintenir les deux alignés raisonnablement bien, vous devez probablement utiliser l'héritage multiple en C ++, mais vous souhaitez limiter certaines de ces classes de base de la même manière que Java restreint une interface par rapport à une classe (c'est-à-dire qu’il spécifie les signatures de fonction mais, du moins dans la plupart des cas, pas les implémentations).

C'est à peine effleurer la surface des différences réelles entre les deux cependant. En réalité, là où le code Java est susceptible de définir des interfaces et des classes qui implémentent ces interfaces, le code C ++ est beaucoup plus susceptible de définir des modèles pouvant fonctionner avec toutes les classes répondant à ses exigences (pas uniquement celles définies spécifiquement pour implémenter l'interface). (s) il spécifie).

Si vous voulez honnêtement un code qui est fondamentalement "Java en utilisant la syntaxe C ++", vous devrez certainement interdire tout ce qui est similaire à ce dernier. Vous devrez limiter votre utilisation des modèles à peu près au niveau de "conteneur de T" pris en charge par les génériques Java. Malheureusement, le code C ++ deviendra un tel désordre que personne ne peut le conserver tel qu'il existe actuellement, sans parler de la possibilité à long terme de le traduire dans un autre langage de programmation.

Si vous voulez vraiment du code pouvant être converti dans une autre langue à l'avenir, efforcez-vous de le rendre aussi propre et lisible que possible. L'idéal est d'écrire du pseudo-code tout en l'exécutant. Des approches C ++ modernes bien écrites et qui idéalisent beaucoup plus étroitement que le sous-ensemble que vous avez suggéré. Quelle que soit la façon dont vous l'écrivez, si vous traduisez jamais en Java, vous devrez traduire le code, pas seulement la syntaxe des instructions individuelles.

Jerry Coffin
la source
De nombreuses fonctionnalités C ++ peuvent être utilisées à certains égards, ce qui correspond bien aux concepts Java, et d’autres non. Certaines parties d'un programme vont nécessiter quelque chose en dehors du sous-ensemble qui se chevauche de la fonctionnalité des langages, et tenter d'écrire des parties telles que "Java en utilisant la syntaxe C ++" va donner lieu à un désastre horrible. Par ailleurs, de nombreuses autres parties du code peuvent nécessiter quoi que ce soit en dehors du sous-ensemble partagé . Il peut être utile d' essayer de rester dans le partage pour les parties du code où il n'y a aucune raison impérieuse de sortir du code .
Supercat
Vraisemblablement où vous dites "peut avoir besoin", vous voulez vraiment dire: "peut ne pas avoir besoin"? En supposant que oui, alors j'ai tendance à être d'accord.
Jerry Coffin le
Ouaip. S'il devient nécessaire de prendre en charge une plate-forme prenant en charge Java mais pas le C ++, des parties du code devront presque certainement être réécrites à partir de rien et peu importe si ces parties ont été écrites à l'aide de techniques conviviales pour Java, car elles ' ll sera quand même réécrit. Il est toutefois possible d’écrire d’autres parties d’une manière qui leur permette d’être migrées sans une réécriture complète et, dans certains cas, les coûts supplémentaires nécessaires pour le faire peuvent être minimes.
Supercat
4
@supercat: OTOH, compte tenu du nombre de plates-formes prenant en charge Java mais pas le C ++, cela me semble être une solution presque entièrement à la recherche d'un problème.
Jerry Coffin le
Pendant un certain temps, la prise en charge des applets Java par navigateur était meilleure que pour les applets C ++. La prise en charge du navigateur pour JavsScript (aucune relation avec Java) a toutefois été suffisamment améliorée pour qu’elle soit prise en charge par les deux.
Supercat
11

Si vous envisagez d'écrire du code dans la langue X, passez le temps nécessaire pour bien apprendre le langage et utiliser toutes les fonctionnalités qu'il offre pour vous aider à résoudre le problème. De mauvaises choses se produisent lorsque vous essayez de faire une traduction "mot à mot" d'une langue à une autre, que ce soit du japonais vers l'anglais ou de Java vers C ++. Il est bien préférable de commencer par bien comprendre le problème et d’exprimer la solution de la manière la plus naturelle pour le langage utilisé.

Il y a des années, j'ai vu un programme C ne comportant aucune indentation et chaque déclaration commençait à la colonne 7, car l'auteur du code était un programmeur Fortran qui utilisait C. D'autres programmeurs Fortran étaient nerveux à propos de ces choses nouvelles appelées pointeurs. Je n'avais pas le cœur de mentionner les pointeurs entre eux, je pense qu'ils se seraient évanouis sur place.

Imaginez embaucher quelqu'un pour maintenir ce code à l'avenir. S'il s'agit d'un bon code C ++, vous pourrez embaucher un développeur C ++ compétent et ils devraient pouvoir s'y retrouver. S'il s'agit de "Java en C ++", ni les développeurs C ++ ni Java n'auront facilement la compréhension du code.

Tom Penny
la source
7

Toutes vos raisons peuvent être réfutées:

Si Java ne fournit pas une fonctionnalité dont dispose le C ++, cela signifie que la fonctionnalité n'est pas bonne, nous devons donc empêcher son utilisation.

Cela ne signifie pas que la fonctionnalité n'est pas bonne (aucune fonctionnalité ne peut être intrinsèquement mauvaise). Cela signifie simplement que la fonctionnalité a été fréquemment mal utilisée (ou impossible à mettre en œuvre en raison de concepts fondamentaux, tels que les pointeurs directs vs le ramassage des ordures). Par définition, Java est conçu pour être plus facile et plus convivial pour les programmeurs, d’où la suppression des fonctionnalités qui se sont révélées facilement abusables.

Le code C ++ avec des fonctionnalités spécifiques à C ++ (par exemple, les fonctions ami, l'héritage multiple) ne peut être maintenu ou révisé que par les programmeurs C ++, mais si nous écrivons simplement C ++ comme Java (sans fonctionnalité spécifique au langage C ++), le code peut être maintenu ou révisé par les deux. Programmeurs C ++ et Java.

Oh ça peut l'être? Voyons le code C ++ le plus simple:

int len = mystring->size();

Oups, aucune fonctionnalité "spécifique à une langue" n'est utilisée, pourtant, les développeurs Java ne la maintiennent pas! Parce qu'en Java, vous déréférencez avec "." alors qu'ici c'est "->.

On vous demandera peut-être de convertir le code en Java un jour.

Ou C #. Ou Haskell. Ou Python. Ou Ruby. Ou COBOL (oui, vous pouvez!). Comment pouvez-vous dire l'avenir?

Le code sans fonctionnalités spécifiques à C ++ est généralement plus facile à gérer.

Tout à fait opposé. Chaque fonctionnalité a été introduite afin de rendre la programmation plus facile et donc plus facile à gérer. Ex: prenez un programme fonctionnant sur des flotteurs. Maintenant, mettez à niveau pour gérer les nombres complexes. Une surcharge d'opérateur à la rescousse!

Chaque fonctionnalité spécifique au langage C ++ (par exemple: l'héritage multiple) devrait avoir des alternatives à implémenter en Java. Si ce n'est pas le cas, cela signifie que le modèle de conception ou l'architecture du code est problématique.

Mais Java a plusieurs héritages! Cela s'appelle "interface". L'implémentation de Java est une solution de contournement problématique pour éviter le diamant redouté causé par tout ce qui en dérive Object. Cela se fait en introduisant interfacequel est le seul but est d'être quelque chose qui ne dérive pas Object. C ++ n'a jamais eu ce problème - il n'y a pas de base commune obligatoire, donc chaque classe peut fonctionner comme une interface sans le diamant redouté.

Note latérale: Java a récemment introduit ... des méthodes concrètes dans les interfaces. Ajout d'une fonctionnalité C ++ devait toujours résoudre un problème qui n'existait jamais.

Vous avez également mentionné très peu "de choses que C ++ possède mais que Java ne fait pas". L'une des plus grandes différences entre C ++ et Java réside dans le contrôle de la disposition de la mémoire. Vous pouvez créer un tableau de pointeurs sur des objets (comme en Java) OU vous pouvez créer un bloc de mémoire contigu. Maintenant, si je devais m'inquiéter d'une fonctionnalité C ++ qui pourrait induire en erreur les développeurs Java, quelque chose d'aussi caché et subtil que celui-ci se placerait sur ma liste beaucoup plus haut que ce qui est évident et reconnaissable à première vue, comme l'héritage multiple ou les opérateurs surchargés.

Ligne de fond: Un code propre est un code propre. Java ou C ++ - même différence. Reste simple. Les complications inutiles sont la principale cause de mauvais code.

Agent_L
la source
Java offre certaines fonctionnalités et garanties qui ne seraient pas supportées dans un langage qui offre toutes les fonctionnalités de C ++. Un langage ne peut pas, par exemple, autoriser le chargement dynamique de types et la gamme complète d'incantations préservant l'identité de Java tout en offrant les formes généralisées d'héritage multiple incluses dans C ++.
Supercat
@sercerc Je ne comprends pas pourquoi vous dites cela ici. La question ne concerne pas les fonctionnalités Java qui ne peuvent pas être reproduites en C ++, il s'agit des fonctionnalités C ++ que Java a ignorées.
Agent_L
Mon point est que certaines fonctionnalités de Java ne sont pas incluses dans C ++, mais plutôt que certaines fonctionnalités de Java sont fondamentalement incompatibles avec d'autres fonctionnalités incluses dans C ++, de telle sorte qu'aucun langage ne peut avoir de types les prenant en charge à la fois (langages tels que C ++ / CLI). ont des types qui prennent en charge les fonctionnalités C ++ et des types qui prennent en charge les fonctionnalités Java-ish, mais ils habitent effectivement des univers distincts avec une interopérabilité limitée).
Supercat
6

Non, vous ne devez généralement pas écrire en C ++ comme s'il s'agissait de Java, et vous ne devez absolument pas omettre les fonctionnalités du langage C ++ qui ne sont pas présentes en Java.

D'une part, Java est un déchet ordonné et n'a donc pas d'équivalent du mot clé "delete" de C ++. Bon, vous implémentez donc un programme sans suppression, car selon vos règles, il n'est pas autorisé.

Félicitations, vous avez maintenant une fuite de mémoire;). Ce n'est pas théorique non plus - j'ai vu cette situation se produire dans un jeu open source.

De même, Java n’a rien de comparable aux pointeurs C ++, ce qui exclut de nombreuses conventions d’appel de fonction courantes.

Il y a des fonctionnalités de C ++ que vous devriez peut-être éviter (voir ci-dessous), mais "ne pas être en Java" n'est pas un bon test décisif.


Les meilleures directives seraient les suivantes:

  1. Écrivez un code adapté à votre langue, à votre environnement et à vos outils.
  2. Écrivez un code que votre équipe peut comprendre.
  3. Assurez-vous que votre équipe est compétente dans le domaine donné.

Item (3) signifie que vous ne devriez pas avoir de code pour programmeurs Java en C ++ sans les avoir formés en C ++. Il y a des différences subtiles mais très importantes qu'ils pourraient ne pas apprendre s'ils essayaient de le traiter comme un étrange dialecte de Java.

L'élément (2) signifie que, si votre héritage est particulièrement inconfortable pour votre équipe (par exemple) et s'il existe une solution adéquate qui ne l'utilise pas, il peut être préférable d'utiliser cette solution alternative. Cela dépend toutefois de votre équipe. D'autre part, si votre équipe est plus mal à l'aise avec cette solution alternative qu'avec l'héritage multiple, utilisez l'héritage multiple!


Enfin, il existe des fonctionnalités de langage C ++ qui, on peut le nier, devraient être évitées. Si vous voulez savoir ce que c'est, demandez aux programmeurs C ++ , plutôt qu'aux programmeurs d'un autre langage. Quelques exemples pour commencer sont l' arithmétique de pointeur (pas de consensus universel) et goto.

Ethan Kaminski
la source
6

Il y a déjà de bons points dans d'autres réponses, mais j'aimerais apporter une réponse plus complète, en répondant à vos questions et à vos déclarations individuellement.


Si Java ne fournit pas une fonctionnalité dont dispose le C ++, cela signifie que la fonctionnalité n'est pas bonne, nous devons donc empêcher son utilisation.

Cela a été assez bien répondu: Java n'est pas "la bonne partie" de C ++, et il n'y a aucune raison de le penser.

En particulier, bien que les mérites de chaque fonctionnalité C ++ individuelle soient discutables, de nombreuses fonctionnalités de C ++ 11 / C ++ 14 qui ne font pas partie de Java ne sont pas nécessairement exclues car les concepteurs Java pensaient qu’elles étaient une mauvaise idée. À titre d’exemple, jusqu’à la version 8, Java n’avait pas de lambda, mais ils ont été introduits au C ++ dans la norme C ++ 11. Avant Java 8, votre hypothèse selon laquelle les fonctionnalités C ++ manquantes dans Java étaient absentes de par leur conception, car elles ne sont "pas bonnes" aurait laissé entendre que lambdas en tant que fonctionnalité de langage n'est "pas bon" (à la grande horreur des LISPers, probablement assez horrifié d'apprendre que vous semble réellement comme Java). Mais maintenant, les concepteurs Java ont mis leur Stamp of Approval (TM) sur les lambdas, ils sont donc maintenant une bonne chose.

Pour aller un peu plus loin, même dans Java 8, les lambdas-as-closures ne sont pas aussi flexibles que les lambdas de C ++ 14, mais cela peut être dû aux limitations de l'architecture de la machine virtuelle Java plutôt qu'à une décision consciente que l'approche plus flexible est mauvaise pour un client. perspective de conception de la langue.


Le code C ++ avec des fonctionnalités spécifiques à C ++ (par exemple, les fonctions ami, l'héritage multiple) ne peut être maintenu ou révisé que par les programmeurs C ++, mais si nous écrivons simplement C ++ comme Java (sans fonctionnalité spécifique au langage C ++), le code peut être maintenu ou révisé par les deux. Programmeurs C ++ et Java.

C'est la principale chose à laquelle je voulais réagir.

De manière générale, il peut être intéressant d'obtenir des critiques de code de programmeurs qui ne connaissent pas très bien le langage que vous utilisez. Ils peuvent vous donner de précieux commentaires sur la clarté de vos noms et commentaires de fonction / méthode, et (comme votre question l’implique correctement), si la langue est similaire à une ou plusieurs langues qu’ils connaissent déjà, ils pourront peut-être suivre le flux de base du programme. et potentiellement attraper des erreurs de logique.

Cependant, il est pas le cas que ce genre d'examen ne sera jamais « aussi bien que » ou « équivalent à » examen des développeurs qui savent en fait la langue que vous utilisez. Cela est essentiellement dû au fait que donner à une langue l' apparence d'une autre dissimulera en général des différences subtiles, tandis que se faire se comporter comme une autre (en particulier dans le cas de C ++ et de Java) peut être non idiomatique pour le langage et / ou peut-être encore trop déroutant pour les relecteurs.

Tout d’abord, réfléchissons à ce que cela signifierait de faire en sorte que C ++ "ressemble" à Java. Comme un cas simple, vous pouvez utiliser newpour instancier des objets, comme en Java:

Foo foo = new Foo();

Mais les objets instanciés de cette façon utilisent ->au lieu d' .appeler des méthodes, donc si vous voulez que les appels de méthode ressemblent à Java, vous devez plutôt écrire:

Foo& foo = *new Foo();

Mais cela n’est pas idiomatique; en particulier, la mémoire doit ensuite être nettoyée à l'aide d' un codedelete &foo que certains développeurs expérimentés en C ++ pourraient même ne pas comprendre . De toute façon, il y a de drôles de symboles non-Java qui parsèment, donc nous ne pouvons pas vraiment faire en sorte que le langage "ressemble" à Java. (Vous pouvez éliminer en *newutilisant #define New *new, ou, pire, #define new *newmais ensuite vous implorez simplement que vos collègues développeurs vous haïssent.) Et, comme mentionné ci-dessus, deleten'existe pas en Java, donc dans tous les cas (comme mentionné dans une autre réponse ) vous ne pouvez pas vraiment faire en sorte que l’utilisation des objets ressemble à celle qu’elle a en Java sans fuites de mémoire.

Mais le C ++ moderne inclut des pointeurs partagés intelligents, qui se comportent beaucoup comme les références de variable gérées par la mémoire de Java. Donc, partout en Java que vous pourriez écrire Foo foo = new Foo();, vous pouvez écrire:

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

Vous utilisez maintenant une fonctionnalité de langage qui ressemble beaucoup à Java sous le capot. Mais tout à coup, vous avez beaucoup à expliquer aux relecteurs non-C ++: qu'est-ce que c'est shared_ptr? Quels sont les subtils "pièges" de make_shared? (Il utilise une transmission parfaite, qui présente certains cas d'échec et peut conduire à l'appel du "mauvais" constructeur.) Pourquoi les méthodes doivent-elles être appelées avec ->, mais l'utilisation .de certaines méthodes est autorisée par le compilateur? ( shared_ptra ses propres méthodes.) Si la méthode Foo::reset(void)existe, un développeur non averti peut essayer de l'appeler foo.reset(), qui (s'il n'y a qu'un seul pointeur partagé pointant vers cette instance ou Foolorsque l'appel a lieu) supprimera la mémoire sous-jacente et sera annulée foo, et Les développeurs Java ne risquent pas d'attraper ce problème.

De plus, C ++ a beaucoup de pièges qui sont spécifiques à la langue. Autant que je sache, la plupart des développeurs C ++ apprennent à gérer ces écueils en développant progressivement leur propre langage pour des pratiques C ++ "sûres", ce qui est souvent assez unique pour eux ou pour leur équipe de développement (voir par exemple la réponse existante qui mentionne la Les pratiques de codage de Google et le commentaire à ce sujet indiquant que "les vétérans chevronnés du C ++ rejettent généralement les directives de codage de Google"). Toutes les affirmations selon lesquelles le langage pourrait être trop compliqué, semble-t-il (selon mon expérience, au moins), se heurtent généralement à une variation de "bien, arrêtez de le mal utiliser". Je sais que cela est une vue très négative de la communauté C ++, et il y a certainement des développeurs expérimentés plus disposés à aider les apprenants langue, mais il ne semble être une certaine attitude défensive vis-à-vis, par exemple, d’un comportement indéfini (voir par exemple une grande partie de la discussion dans le lien «pièges» ci-dessus).

Les développeurs Java ne seront tout simplement pas utiles pour trouver et corriger ces pièges via la révision du code.


On vous demandera peut-être de convertir le code en Java un jour.

Il est tout à fait valable - même louable - d'essayer de prendre en compte ce qui pourrait arriver à votre code à l'avenir pendant la phase de conception.

Mais, premièrement, cette considération particulière semble être une possibilité lointaine: le code est généralement soit réutilisé tel quel (par exemple, vous pouvez brancher tout ou partie du code C ++ actif dans un logiciel Java futur utilisant une interface JNI), ou le réécrire entièrement à la place. que directement manuellement "transcrit".

Et, deuxièmement, vous dites plus tard:

Chaque fonctionnalité spécifique au langage C ++ (par exemple: l'héritage multiple) devrait avoir des alternatives à implémenter en Java ....

Cela annule essentiellement votre point "converti en Java". Si le logiciel est écrit en C ++ idiomatique puis converti en Java idiomatique, il n’ya aucune raison de s’attendre à ce que cette conversion soit (ou pourrait!) Être réalisée en appliquant un mappage précis un à un des fonctionnalités C ++ aux fonctionnalités Java.


Le code sans fonctionnalités spécifiques à C ++ est généralement plus facile à gérer.

Vous ne comprenez pas ce que vous voulez dire ici, mais je suis en quelque sorte d’accord avec une partie de ceci: à moins que vous ne soyez très prudent, et même lorsque vous êtes prudent, les fonctionnalités C ++ peuvent entraîner des problèmes de maintenabilité. Le C ++ FQA Lite (un site Web critique du langage et de ses adeptes de quelqu'un qui semble au moins le comprendre assez bien) déclare que

... 80% des développeurs comprennent au plus 20% du langage. Ce n'est pas la même chose pour 20%, alors ne comptez pas sur eux pour comprendre le code de chacun.

VEUILLEZ NOTER: Si vous êtes un fan de C ++ et que vous répondez à ce point dans ma réponse, vous êtes enclin à passer directement aux commentaires pour faire valoir que l'auteur de la FQA ne comprend pas réellement le C ++ ou qu'il est fallacieux dans la plupart de ses arguments. , notez que (1) deux phrases exactement après que je le cite, je reconnais que la FQA est une source très partiale, et (2) peu importe ce que je veux dire si l’auteur de la FQA comprend ou non C ++ et je n'essaie pas de critiquer le C ++, et vous devriez lire le reste du message sans supposer que je suis anti-C ++ simplement parce que j'ai cité la FQA. Fin de la note.

De même, Linus Torvalds déteste le C ++ pour cette raison (avertissement: link implique beaucoup de jurons, dans le style tristement célèbre de Linus).

De toute évidence, ces questions sont très biaisées, mais même les partisans du C ++ disent souvent qu'il ne faut pas utiliser l'intégralité de l'ensemble des fonctionnalités du langage (à nouveau, reportez-vous aux consignes de codage de Google; Bjarne Stroustrup, créateur du C ++, par exemple). , a publiquement déclaré: "Dans C ++, il existe un langage beaucoup plus petit et plus propre qui a du mal à sortir").

Je pense donc que l’idée selon laquelle les fonctionnalités C ++ sont trop faciles à utiliser, en particulier si vous venez de l’arrière-plan Java, a du mérite. En outre, l’idée d’atténuer ces problèmes en se limitant à un sous-ensemble de la langue présente des avantages.

Cependant, décider quel sous-ensemble utiliser en utilisant un langage différent ne semble pas être la bonne approche, à moins que le "langage différent" soit C, car il existe vraiment un sous-ensemble du langage C ++ ressemblant à C. (Linus fait référence à cela dans son discours ci-dessus, et Scott Meyers appelle même ce sous-ensemble un "sous-langage".) Le paradigme d'exécution de Java (ramassé, fonctionnant sur une machine virtuelle) est tellement différent du C ++ qu'il est il n’est pas clair qu’il existe des leçons utiles à tirer de l’utilisation de C ++, et comme indiqué ci-dessus, essayer de tirer des leçons de C ++ directement à partir de Java peut conduire à un code très non idiomatique.

Au lieu de cela, essayez de définir votre "sous-ensemble acceptable" du langage sur une compréhension de la façon dont le langage peut être utilisé idiomatiquement. Si vous souhaitez un sous-ensemble assez restrictif qui tire toujours parti de nombreuses fonctionnalités de C ++ autres que celles proposées par C, la directive de codage susmentionnée de Google pourrait être un bon point de départ. Bien sûr, vous aurez des développeurs qui disent qu’il n’ya "pas d’argument rationnel" pour certaines restrictions de Google , mais à moins que vous ne cherchiez à engager Alexandrescu hors de son travail sur le langage D (qui devrait vous dire quelque chose), probablement d'accord. C'est certainement mieux que d'essayer de transformer le C ++ en Java.

Un autre bon point de départ pour un ensemble de directives de code est les nouvelles directives de base C ++ , un travail en cours de réalisation de Bjarne Stroustrup et Herb Sutter.

Le seul autre moyen de remédier aux faiblesses du C ++ consiste à choisir un langage différent. On dirait que vous aimez Java et que vous pensez qu'il est possible que ce projet soit éventuellement converti en Java. Comme indiqué dans une autre réponse, vous pouvez simplement ... commencer par Java.

Il y a deux raisons pour lesquelles vous pourriez vraiment avoir besoin d'utiliser autre chose que Java:

  1. Vous avez vraiment besoin des performances d'exécution. Dans ce cas, traiter le C ++ comme s'il s'agissait de Java ne vous aiderait probablement pas, car des techniques similaires à Java, telles que les pointeurs partagés, altèrent les performances d'exécution.
  2. Le logiciel doit fonctionner sur une plate-forme obscure qui ne prend pas encore en charge la machine virtuelle Java. Dans ce cas, vous êtes probablement coincé avec des langues ayant des interfaces GCC ou Clang. C et C ++ sont des candidats évidents, mais vous pouvez également examiner quelque chose comme Rust. (Prise rapide: je n'ai pas beaucoup utilisé Rust, mais il a l'air génial et j'ai hâte de travailler sur un projet majeur de Rust dès que je peux, et je pense que tous ceux qui envisagent de démarrer un projet C ++ devraient envisager Rust comme alternative.)

Chaque fonctionnalité spécifique au langage C ++ (par exemple: l'héritage multiple) devrait avoir des alternatives à implémenter en Java. Si ce n'est pas le cas, cela signifie que le modèle de conception ou l'architecture du code est problématique.

J'ai déjà abordé cette question un peu, mais j'ai intentionnellement omis votre deuxième phrase.

Je ne suis pas convaincu que quelque chose du genre constexpr, ce qui n'aurait aucun sens dans un langage partiellement JIT comme Java, est une indication d'architecture invalide. Je suis plus ouvert à l'idée que l'utilisation excessive de la méta-programmation de gabarits puisse poser plus de problèmes qu'elle n'en vaut la peine, en particulier à l'heure constexpractuelle pour l'évaluation des fonctions au moment de la compilation, mais il est clair constexprqu'il n'y a pas de défaut de conception si utilisez-le: vous vous assurez simplement que certains calculs sont effectués avant même d'exécuter le code, ce qui représente un gain de performances impressionnant (voir, par exemple, cette entrée pour le problème à n corps de The Benchmark Game , qui surpasse toutes les entrées, sauf une autre écrit en C ++,

Kyle Strand
la source
5
L'auteur de la FQA tombe définitivement dans le groupe "comprendre au plus 20% de la langue". Quelques réponses fausses sur le plan factuel, et bien d’autres encore qui manquent à l’esprit, illustrées par strawman après strawman.
Ben Voigt
2
Beaucoup (presque toutes?) Des plaintes dans la FQA C ++ sont absurdes. Les langues modernes sont énormes. C ++ est plutôt petit comparé à Python, Ruby, Perl et, oui, à Java. Poser une question fondamentale dans ces langues sur stackoverflow et la première réponse est presque inévitablement le long des lignes de « Pourquoi ne pas vous import SomeVeryBasicPackageet juste faire cela ? » Poser une question avancée et la première réponse est presque inévitablement le long des lignes de « Pourquoi ne pas vous import SomeMagicalPackageet faites juste que ? »
David Hammen
1
@DavidHammen Je pense que la division 80/20 fait référence aux fonctionnalités de base du langage, pas seulement aux composants de bibliothèque standard. Dans ce cas, les langages que vous mentionnez, à l'exception peut-être de Perl, ne semblent vraiment pas être aussi gros et compliqués que le C ++. En tout cas, c'était une très petite partie de ma réponse, et j'ai reconnu que c'était une source biaisée.
Kyle Strand
1
Les langages VM / gérés sont évidemment beaucoup plus compliqués sous la surface, mais je veux dire compliqués du point de vue de l'utilisation.
Kyle Strand
1
Je ne sais pas du tout si votre théorie est correcte, bien que dans mon cas, j'ai définitivement appris le C ++ et le C séparément, et ma classe de C ++ était vraiment très complète. Mais la citation complète au sujet de la répartition 20/80 est que chaque programmeur connaît un autre 20% de la langue, qui ne serait pas expliqué par la plupart des programmeurs d'apprendre la partie C de la langue de façon indépendante. Quoi qu'il en soit, si vous souhaitez expliquer en détail comment le C ++ permet une programmation plus robuste (je prétend l'avoir déjà vue mais je ne comprends pas), nous ferions probablement mieux de le faire dans une salle de discussion ou quelque chose du genre plutôt que dans les commentaires. .
Kyle Strand
5

Supposons que je suis limité à l’utilisation de C ++ par l’environnement du projet. Est-il bon d'empêcher l'utilisation de certaines fonctionnalités du langage que C ++ possède mais que Java n'a pas (par exemple: héritage multiple, substitution d'opérateur)?

Non.

Si "par l'environnement du projet" vous êtes limité à utiliser le C ++, alors il est inutile de penser à une autre technologie, même si vous préférez / espérez personnellement l'utiliser / l'évangéliser.
Que "Technology X" ou "Y" prenne en charge une fonctionnalité donnée ne devrait avoir aucune incidence sur la manière dont vous construisez votre application C ++.
C'est une application C ++, vraisemblablement pour une "bonne raison" (maintenant ou dans le passé), vous devriez donc l'écrire en tant qu'application C ++, en utilisant ce que cette "boîte à outils" fournit.

Si et quand il est nécessaire de porter l'application vers une autre technologie, alors (et seulement alors), vous pourriez envisager des fonctionnalités sur d'autres plates-formes. Il ne sert à rien de "se couper le nez pour contrarier votre visage", au risque que quelque chose se produise. Rappelez-vous cependant que la réécriture en gros est une opération coûteuse et risquée que la direction ne pourra probablement pas entreprendre sans une très bonne raison de le faire.

Il y a quelques années, il y avait eu un débat similaire («utiliser ou ne pas utiliser») dans le monde Visual Basic [.Net], où quelqu'un avait eu la brillante idée d'écrire des applications Visual Basic sans utiliser aucun des [langages de base]. fonctionnalité fournie par l'espace de noms Microsoft.VisualBasic. Ce serait comme essayer d'écrire une application C ++ sans le std :: namespace; OK, c’est possible, mais pourquoi, sur terre, est-ce que quelqu'un de sensé pourrait en prendre la peine?

Phill W.
la source
1
Dernière chose à propos de Visual Basic: le problème avec ces bibliothèques de fournisseurs est qu’elles sont propriétaires. Leur utilisation, c'est s'enchaîner avec ce fournisseur. Le fournisseur appréciera que vous soyez enchaîné, mais vous ne le ferez pas à long terme: vous ne pouvez pas utiliser le logiciel d'un autre fournisseur sans réécrire tout ce qui repose sur des fonctionnalités spécifiques du fournisseur. Plus vous utilisez une fonctionnalité spécifique à un fournisseur, plus le coût de changement de fournisseur devient coûteux, ce qui permet à votre fournisseur d'imposer des modifications. C'est l'une des raisons pour lesquelles le logiciel libre (comme dans la liberté!) Est si important.
cmaster
L' Microsoft.VisualBasicespace de noms est un peu exagéré. Cela fait de nombreuses années que je ne l'ai pas utilisé pour la dernière fois, mais au moins au début, il s'agissait principalement d'une compatibilité en amont avec VB6 (et / ou de faire en sorte que les programmeurs VB6 se sentent «chez eux»); il fournissait principalement des fonctionnalités déjà disponibles dans le reste du cadre sous une forme plus moderne (et mieux intégrée); il était donc rarement logique de l'utiliser dans les nouveaux projets. Au contraire, l' std::espace de noms est l'endroit où réside la bibliothèque standard entière. L'éviter, ce serait comme éviter l'ensemble du BCL dans .NET.
Matteo Italia
2

Les réponses actuelles disent toutes que c'est une mauvaise chose à faire, car vous devriez tirer parti du langage que vous utilisez et également expliquer pourquoi une fonctionnalité C ++ n'est pas «mauvaise» simplement parce qu'elle n'est pas en jave. Je vais répondre à cela sous un angle différent.

Éviter les fonctionnalités C ++ complexes telles que l'héritage multiple, la surcharge des opérateurs et la définition de votre propre modèle est une chose.

Mais tout problème qui fait plus que la tâche la plus simple:

  • alloue de la mémoire,
  • relie cet argent avec des points
  • alors construire des structures de données
  • permet ensuite à la mémoire d'être réutilisée lorsqu'elle est sécuritaire de le faire

Il n'y a pas un sous-ensemble commun de Java et C ++ qui permette ce qui précède, par conséquent, ce que vous demandez est impossible à faire. (Si vous posiez des questions sur Java et C #, vous auriez beaucoup plus de chances, car ils utilisent tous les deux des éboueurs.)

Cependant, vous pourriez exiger que le code soit écrit de manière à ce qu'un développeur Java puisse comprendre ce qui se passe (mais pas le "comment" détaillé), ce qui serait judicieux.

Vous pouvez également concevoir votre propre langage que vous avez implémenté à la fois en C ++ et en JAVA .....

Ian
la source
0

Personne ne devrait écrire un code que les autres développeurs ne comprennent pas. Si vous pensez que le verrouillage linguistique est un problème, attendez qu'il soit verrouillé par le développeur. L'un est plus susceptible de vous tenir en otage que l'autre.

Il n'y a vraiment aucune raison technique. Ce que vous avez créé est un scénario dans lequel un langage a été utilisé pour une raison quelconque, mais que de nombreux développeurs actuels et peut-être futurs ne le comprennent pas vraiment.

J'imagine que les développeurs Java sont susceptibles d'écrire le C ++ comme ils l'écrivent en Java, alors pourquoi en faire une règle. Vous découvrirez peut-être certaines fonctionnalités spécifiques à C ++ qui sont plus faciles à implémenter et à gérer avec un peu d’instructions / documentation C ++ pour vos développeurs Java que la grosse boule de désordre Java avec laquelle elles seraient autrement coincées.

Cela a été un argument sur les problèmes des programmeurs BASIC passant à des langages orientés objet. Ce n'est pas qu'ils mettent en œuvre des pratiques de POO au détriment des nouveaux développeurs qui ne le comprennent pas, mais qu'ils ne le mettent pas du tout. S'ils le font, ils se trompent généralement. Si quelque chose est mal fait, il faut l’enlever quelle que soit la raison.

Autre que quelqu'un copiant et collant aveuglément du code, il le fera dans de nombreux domaines qu'il ne comprend pas de toute façon.

JeffO
la source