Que peut faire le C ++ qui est trop difficile ou désordonné dans un autre langage?

StackOverflow https://stackoverflow.com/questions/423335

  •  05-07-2019
  •  | 
  •  

Question

Je pense toujours que le C ++ offre des choses impossibles à battre. Ce n'est pas mon intention de déclencher une guerre des flammes ici, s'il vous plaît, si vous avez des opinions bien arrêtées sur le fait de ne pas aimer le C ++, ne les diffusez pas ici. Les gourous du C ++ aimeraient savoir pourquoi ils s’y tiennent.

Je suis particulièrement intéressé par les aspects peu connus ou sous-utilisés du C ++.

Modifier: Les gens, veuillez au moins lire rapidement les autres réponses pour vous assurer de ne pas dupliquer ce qui a déjà été dit. Si vous êtes d'accord avec ce que quelqu'un d'autre a dit, invitez-le à remonter!

Était-ce utile?

La solution

Je suis resté avec C ++ car il reste le langage polyvalent le plus performant pour les applications qui doivent combiner efficacité et complexité. A titre d'exemple, j'écris un logiciel de modélisation de surface en temps réel pour les appareils portables du secteur de la topographie. Compte tenu des ressources limitées, Java, C #, etc. ne fournissent tout simplement pas les caractéristiques de performance nécessaires, alors que les langages de bas niveau tels que C sont beaucoup plus lents à développer en raison des caractéristiques d’abstraction plus faibles. La gamme de niveaux d'abstraction disponibles pour un développeur C ++ est énorme. À un extrême, je peux surcharger les opérateurs arithmétiques de telle sorte que je puisse dire quelque chose comme MaterialVolume = DesignSurface - GroundSurface tout en exécutant un nombre. de différents tas pour gérer la mémoire le plus efficacement possible pour mon application sur un appareil spécifique. Combinez cela avec une multitude de sources disponibles gratuitement pour résoudre pratiquement tous les problèmes courants, et vous avez un sacré langage de développement puissant.

C ++ est-il toujours la solution de développement optimale pour la plupart des problèmes dans la plupart des domaines? Probablement pas, même si à la rigueur il peut encore être utilisé pour la plupart d'entre eux. Est-ce toujours la meilleure solution pour développer efficacement des applications hautes performances? IMHO sans aucun doute.

Autres conseils

RAII / finalisation déterministe . Non, la récupération de place n'est pas aussi efficace lorsque vous avez affaire à une ressource rare et partagée.

Accès illimité aux API du système d'exploitation .

Se tirer dans le pied.

Aucune autre langue n'offre un tel éventail d'outils créatifs. Pointeurs, héritage multiple, modèles, surcharge des opérateurs et préprocesseur.

Un langage merveilleusement puissant qui offre également de nombreuses possibilités de tir au pied.

Edit: Je m'excuse si mon humble tentative d'humour a choqué certains. Je considère le C ++ comme le langage le plus puissant que j'ai jamais utilisé - avec des capacités de codage au niveau du langage d'assemblage lorsque vous le souhaitez et à un niveau d'abstraction élevé lorsque vous le souhaitez. Le C ++ est ma langue principale depuis le début des années 90.

Ma réponse était basée sur des années d’expérience de la fusillade au pied. C ++ au moins me permet de le faire avec élégance.

La destruction d’objets déterministe donne lieu à de magnifiques modèles de conception. Par exemple, bien que la technique RAII ne soit pas une technique aussi générale que la récupération de place, elle conduit à des fonctionnalités impressionnantes que vous ne pouvez pas obtenir avec GC.

C ++ est également unique en ce sens qu’il dispose d’un préprocesseur Turing-complete. Cela vous permet de préférer (comme dans le cas du différer) beaucoup de tâches de code pour compiler le temps au lieu du temps d'exécution. Par exemple, dans le code réel, vous pouvez avoir une instruction assert () à tester pour ne jamais se produire. La réalité est que cela arrivera tôt ou tard ... et se produira à 3 heures du matin lorsque vous êtes en vacances. L'assertion du préprocesseur C ++ effectue le même test lors de la compilation. Les affirmations au moment de la compilation échouent entre 8 h et 17 h lorsque vous êtes assis devant l'ordinateur en train de regarder la création du code. les affirmations au moment de l'exécution échouent à 3h00 du matin lorsque vous êtes endormi à Hawaii. Il est assez facile de voir la victoire ici.

Dans la plupart des langages, les modèles de stratégie sont définis au moment de l'exécution et génèrent des exceptions en cas d'incompatibilité de type. En C ++, les stratégies peuvent être élaborées au moment de la compilation par l’intermédiaire du préprocesseur et peuvent être garanties typesafe.

Écrire un assemblage en ligne (MMX, SSE, etc.).

Destruction d’objets déterministe. C'est à dire. vrais destructeurs. Facilite la gestion des ressources rares. Permet RAII.

Accès plus facile aux données binaires structurées. Il est plus facile de transformer une région mémoire en structure que de l'analyser et de copier chaque valeur dans une structure.

Héritage multiple. Tout ne peut pas être fait avec des interfaces. Parfois, vous souhaitez également hériter des fonctionnalités actuelles.

Je pense que je vais féliciter le C ++ pour sa capacité à utiliser des modèles pour capturer des expressions et à l'exécuter paresseusement lorsque cela est nécessaire. Pour ceux qui ne savent pas de quoi il parle, ici est un exemple.

Les mixins de modèles fournissent une réutilisation que je n’ai jamais vue ailleurs. Avec eux, vous pouvez créer un objet volumineux avec beaucoup de comportement, comme si vous aviez écrit le tout à la main. Mais tous ces petits aspects de ses fonctionnalités peuvent être réutilisés. C’est particulièrement intéressant pour la mise en œuvre de parties d’une interface (ou de l’ensemble) où vous implémentez un certain nombre d’interfaces. L'objet résultant est ultra-rapide, car tout est en ligne.

La rapidité n'a peut-être pas d'importance dans de nombreux cas, mais lorsque vous écrivez un logiciel composant et que les utilisateurs peuvent combiner des composants de manières inattendues, la vitesse d'inlining et de C ++ semble permettre la création de structures beaucoup plus complexes. créé.

Contrôle absolu de la structure de la mémoire, de l'alignement et de l'accès lorsque vous en avez besoin. Si vous êtes assez prudent, vous pouvez écrire des programmes très conviviaux pour le cache. Pour les programmes multiprocesseurs, vous pouvez également éliminer beaucoup de ralentissements grâce aux mécanismes de cohérence du cache.

(D'accord, vous pouvez le faire en C, en assembleur et probablement en Fortran aussi. Mais le C ++ vous permet d'écrire le reste de votre programme à un niveau supérieur.)

Cela ne sera probablement pas une réponse courante, mais je pense que ce qui distingue le C ++, ce sont ses capacités de compilation, par exemple. modèles et #define. Vous pouvez effectuer toutes sortes de manipulations de texte sur votre programme en utilisant ces fonctionnalités, dont une grande partie a été abandonnée dans des langues ultérieures au nom de la simplicité. Pour moi, cela est bien plus important que n'importe quel bidouillage de bas niveau censé être plus facile ou plus rapide en C ++.

C #, par exemple, n’a pas de véritable fonction macro. Vous ne pouvez pas # inclure un autre fichier directement dans la source, ni utiliser #define pour manipuler le programme en tant que texte. Pensez à chaque fois que vous devez taper mécaniquement du code répétitif et que vous savez qu'il existe un meilleur moyen. Vous avez peut-être même écrit un programme pour générer du code pour vous. Eh bien, le préprocesseur C ++ automatise toutes ces choses.

Les "génériques" La fonctionnalité en C # est également limitée par rapport aux modèles C ++. C ++ vous permet d'appliquer l'opérateur de points à un modèle de type T à l'aveuglette, en appelant (par exemple) des méthodes qui peuvent ne pas exister et en vérifiant si la correction est correcte uniquement lorsque le modèle est réellement appliqué à une classe spécifique. Lorsque cela se produit, si toutes les hypothèses que vous avez faites sur T sont vérifiées, votre code sera compilé. C # ne permet pas ce type ... de type "T". doit en principe être traité en tant qu’objet, c’est-à-dire en utilisant uniquement le plus petit dénominateur commun des opérations disponibles (affectation, GetHashCode (), Equals ()).

C # a supprimé le préprocesseur et les véritables génériques au nom de la simplicité. Malheureusement, lorsque j'utilise C #, je cherche des substituts à ces constructions C ++, qui sont inévitablement plus volumineuses et superposées que l'approche C ++. Par exemple, j’ai vu des programmeurs contourner l’absence de #include de plusieurs manières: liaison dynamique à des assemblys externes, redéfinition des constantes à plusieurs emplacements (un fichier par projet) ou sélection de constantes dans une base de données, etc.

Comme l'a dit un jour Mme Crabapple de The Simpson's, c'est "assez boiteux, Milhouse".

En termes d’informatique, ces fonctionnalités de compilation en C ++ permettent, entre autres, le passage de paramètres appel par nom, qui est connu pour être plus puissant que l’appel par valeur et l’appel par référence.

Encore une fois, ce n’est peut-être pas la réponse habituelle: tout texte d’introduction au C ++ vous avertira de #define, par exemple. Mais ayant travaillé avec une grande variété de langues pendant de nombreuses années et ayant pris en compte la théorie derrière tout cela, je pense que beaucoup de gens donnent de mauvais conseils. Cela semble être particulièrement le cas dans le sous-champ dilué appelé "IT".

Techniquement, je pense qu'il n'y en a pas, vraiment!

Honnêtement, je ne pense pas que C ++ puisse faire quelque chose que le langage D ne puisse pas faire. Quelle que soit la capacité du C ++, elle est toujours plus dure et compliquée que D ou tout autre langage. Même une chose simple, comme une déclaration de classe, est bien plus dure et complexe en C ++ que n’importe quel autre langage.

La seule chose que C ++ puisse faire est d’être compatible avec des millions de lignes de codes déjà écrits en C ++.
C’est la seule chose qu’aucun autre langage que le C ++ ne peut faire:)

Transmission des structures de POD à travers les processus avec un minimum de temps système En d’autres termes, cela nous permet de gérer facilement des blobs de données binaires.

C # et Java vous obligent à mettre votre fonction 'main ()' dans une classe. Je trouve cela étrange, car cela dilue le sens d'une classe.

Pour moi, une classe est une catégorie d'objets dans votre domaine de problèmes. Un programme n'est pas un tel objet. Il ne devrait donc jamais y avoir de cours appelé "Programme" dans votre programme. Cela équivaudrait à une preuve mathématique utilisant un symbole pour se noter - la preuve - à côté de symboles représentant des objets mathématiques. Ce sera juste bizarre et incohérent.

Heureusement, contrairement à C # et Java, C ++ permet des fonctions globales. Cela permet à votre fonction main () d'exister à l'extérieur. Par conséquent, C ++ offre une implémentation plus simple, plus cohérente et peut-être plus vraie de l'idiome orienté objet. C ++ peut donc faire cela, mais C # et Java ne le peuvent pas.

Je pense que la surcharge d’opérateurs est une fonctionnalité plutôt intéressante. Bien sûr, il peut être très mal utilisé (comme dans Boost lambda).

Contrôle étroit des ressources système (en particulier de la mémoire) tout en offrant de puissants mécanismes d'abstraction en option. Le seul langage que je connaisse qui puisse s'approcher du C ++ à cet égard est Ada.

C ++ fournit un contrôle complet sur la mémoire et, par conséquent, rend le flux d’exécution du programme beaucoup plus prévisible. Vous pouvez non seulement spécifier avec précision à quel moment les affectations de temps et les désallocations de mémoire se produisent, vous pouvez définir vos propres tas, avoir plusieurs tas à des fins différentes et indiquer avec précision à quel emplacement des données sont allouées. Ceci est souvent utile lors de la programmation sur des systèmes embarqués / temps réel, tels que des consoles de jeux, des téléphones portables, des lecteurs MP3, etc., lesquels:

  1. impose des limites supérieures strictes en matière de mémoire, qui est facile à atteindre (contrairement à un PC qui ralentit à mesure que vous manquez de mémoire physique)
  2. a souvent une disposition de mémoire non homogène. Vous souhaiterez peut-être affecter des objets d'un type dans une partie de la mémoire physique et des objets d'un autre type dans un autre.
  3. ont des contraintes de programmation en temps réel. Appeler de manière inattendue le ramasse-miettes au mauvais moment peut être désastreux.

Pour autant que je sache, C et C ++ sont la seule option judicieuse pour faire ce genre de chose.

Eh bien, pour être tout à fait honnête, vous pouvez faire à peu près n'importe quoi si vous êtes prêt à écrire suffisamment de code.

Donc, pour répondre à votre question, non, vous ne pouvez rien faire dans un autre langage que le C ++ ne peut pas faire. C'est juste combien de patience avez-vous et êtes-vous prêt à passer de longues nuits sans sommeil pour le faire fonctionner?

Il y a des choses que les wrappers C ++ facilitent (parce qu'ils peuvent lire les fichiers d'en-tête), comme le développement Office. Mais encore une fois, c’est parce que quelqu'un a écrit beaucoup de code dans "wrap". pour vous dans un RCW ou "Runtime Callable Wrapper"

EDIT: Vous réalisez également que la question est lourde.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top