Question

Récemment, j'ai une idée dangereuse dans la tête après avoir lu cet billet de blog. Cette idée peut être exprimée comme ceci:

Je n'ai pas besoin de la plupart des offres de la bibliothèque standard C ++. Alors, pourquoi ne pas implémenter une version moins générale, mais plus facile à utiliser?

Par exemple, l’utilisation de la STL génère des erreurs de compilateur incompréhensibles et incompréhensibles. Mais je me fiche des allocateurs, des itérateurs et autres. Alors, pourquoi ne pas prendre quelques heures et implémenter une classe de liste chaînée facile à utiliser, par exemple?

Ce que j'aimerais savoir de la communauté StackOverflow est la suivante: quels sont les dangers, les inconvénients et les avantages possibles de & "Rouler mon propre &"; pour la plupart des fonctionnalités existantes en C ++?

Modifier: Je pense que les gens m'ont mal compris à propos de cette idée. L'idée était de comprendre si je pouvais implémenter un très très petit ensemble de fonctionnalités STL grandement simplifiées - plutôt comme un projet destiné à m'enseigner les structures de données, etc. Je ne propose pas de réinventer toute la roue à partir de la base, juste la partie dont j'ai besoin et que je veux apprendre. Je suppose que ce que je voulais savoir, c'est si la complexité de l'utilisation du TSL justifie la création d'une version plus petite et plus simple d'elle-même.

Réutilisation de boost ou similaire.

La plupart de mes codes sont destinés à l'université et nous ne sommes pas autorisés à utiliser des bibliothèques externes. C’est donc soit la bibliothèque standard C ++, soit mes propres classes.

L'objectivité de cette question.

Cette question n'est pas subjective. Ce ne devrait pas non plus être un wiki de communauté, car ce n'est pas un sondage. Je souhaite des arguments concrets mettant en évidence un avantage ou un inconvénient qui pourrait éventuellement survenir avec mon approche. Contrairement à la croyance populaire, ce n’est pas une opinion, mais une expérience ou de bons arguments logiques.

Format.

N'affichez qu'un seul inconvénient ou un seul avantage par réponse. Cela permettra aux gens d'évaluer des idées individuelles au lieu de toutes vos idées en même temps.

Et s'il vous plaît ...

Pas de guerres de religion. Je ne suis pas un fan de n'importe quelle langue. J'utilise ce qui est applicable. Pour les graphismes et la compression de données (ce sur quoi je travaille en ce moment), cela semble être du C ++. Veuillez limiter vos réponses à la question, sinon elles seront votées.

Était-ce utile?

La solution

  

Alors, pourquoi ne pas implémenter un moins   version générale, mais plus facile à utiliser?

Parce que vous ne pouvez pas. Parce que quoi que vous puissiez dire du C ++, ce n’est pas un langage simple, et si vous n’êtes pas déjà très bon, l’implémentation de votre liste chaînée sera boguée.

Honnêtement, votre choix est simple:

Apprenez le C ++ ou ne l'utilisez pas. Oui, C ++ est couramment utilisé pour les graphiques, mais Java possède également des bibliothèques OpenGL. Il en va de même pour C #, Python et pratiquement tous les autres langages. Ou C. Vous n'avez pas besoin d'utiliser C ++.

Mais si vous l'utilisez, apprenez-le et utilisez-le correctement.

Si vous voulez des chaînes immuables, créez votre chaîne en tant que const.

Et quelle que soit son implémentation sous-jacente, le STL est remarquablement simple à utiliser.

Les

erreurs de compilation C ++ peuvent être lues, mais cela prend un peu de pratique. Mais plus important encore, ils ne sont pas exclusifs au code STL. Vous les rencontrerez, peu importe ce que vous ferez et les bibliothèques que vous utiliserez. Alors, habituez-vous à eux. Et si vous vous y habituez quand même, vous pouvez aussi bien utiliser STL.

En dehors de cela, quelques autres inconvénients:

  • Personne d'autre ne comprendra votre code. Si vous posez une question sur SO à propos de std :: vector, ou d'itérateurs bidirectionnels, toute personne connaissant bien c ++ peut répondre. Si vous demandez à propos de My :: CustomLinkedList, personne ne pourra vous aider. Ce qui est regrettable, car rouler le vôtre signifie également qu'il y aura plus de bugs pour lesquels demander de l'aide.
  • Vous essayez de guérir le symptôme plutôt que la cause. Le problème est que vous ne comprenez pas le C ++. STL est juste un symptôme de cela. Eviter STL ne fera pas, comme par magie, que votre code C ++ fonctionne mieux.
  • Les erreurs du compilateur. Oui, ils sont méchants à lire, mais ils sont là. Dans le TSL, beaucoup de travail a été fait pour s'assurer qu'une mauvaise utilisation déclencherait des erreurs de compilation dans la plupart des cas. En C ++, il est très facile de créer un code qui compile, mais ne fonctionne pas. Ou semble fonctionner. Ou fonctionne sur mon ordinateur, mais échoue mystérieusement ailleurs. Votre propre liste chaînée déplacerait certainement davantage d'erreurs vers l'exécution, où elles resteraient non détectées pendant un moment et seraient beaucoup plus difficiles à localiser.
  • Et encore une fois, ce sera un buggy. Croyez-moi. J'ai vu de très bons programmeurs C ++ écrire une liste chaînée en C ++ uniquement pour découvrir un bogue après l'autre, dans des cas de frontière obscurs. Et C ++ est tous les cas frontaliers. Votre liste chaînée gérera-t-elle la sécurité des exceptions correctement? Garantira-t-il que tout est dans un état cohérent si la création d'un nouveau nœud (et donc l'appel du constructeur du type d'objet) lève une exception? Qu'il ne perdra pas de mémoire, que tous les destructeurs appropriés seront appelés? Sera-ce en tant que type-safe? Sera-ce comme performant? Il y a beaucoup de problèmes à résoudre lors de l'écriture de classes de conteneur en C ++.
  • Vous manquez l'une des bibliothèques les plus puissantes et les plus flexibles existantes, dans tous les langages . La STL peut faire beaucoup de problèmes, même avec la bibliothèque de classes gigantesque de Java. C ++ est déjà assez dur, pas besoin de perdre les quelques avantages qu’il offre.
  

Je ne me soucie pas des allocateurs,   itérateurs et similaires

Les allocateurs peuvent être ignorés en toute sécurité. Vous n'avez presque même pas besoin de savoir qu'ils existent. Les itérateurs sont brillants et les résoudre vous éviterait beaucoup de maux de tête. Pour utiliser STL de manière efficace, vous ne devez comprendre que trois concepts:

  • Containers: Vous en connaissez déjà. vecteurs, listes chaînées, cartes, ensembles, files d'attente, etc.
  • Itérateurs: abstractions qui vous permettent de naviguer dans un conteneur (ou dans des sous-ensembles d'un conteneur ou dans une autre séquence de valeurs, en mémoire, sur disque sous la forme de flux ou calculés à la volée).
  • Algorithmes: algorithmes communs fonctionnant sur n'importe quelle paire d'itérateurs. Vous avez trié, for_each, find, copy et bien d’autres.

Oui, la STLest petite comparée à la bibliothèque de Java, mais elle combine une puissance surprenante lorsque vous combinez les 3 concepts ci-dessus. Il y a un peu de courbe d'apprentissage, parce que c'est une bibliothèque inhabituelle. Mais si vous passez plus d'un jour ou deux avec le C ++, cela vaut la peine d'apprendre correctement.

Et non, je ne suis pas votre format de réponse, car je pensais qu'il serait plus utile de vous donner une réponse détaillée. ;)

Modifier:

Il serait tentant de dire qu’un avantage de rouler vous-même est que vous en apprendrez plus sur le langage, et peut-être même pourquoi le STL est l’une de ses grilles de sauvegarde. Mais je ne suis pas vraiment convaincu que ce soit vrai. Cela peut fonctionner, mais cela peut aussi se retourner contre vous.

Comme je l’ai dit ci-dessus, il est facile d’écrire du code C ++ qui semble fonctionner. Et quand cela cesse de fonctionner, il est facile de réorganiser quelques éléments, tels que l'ordre de déclaration des variables, ou d'insérer un peu de remplissage dans une classe, pour que celle-ci apparemment fonctionne à nouveau. Qu'allez-vous apprendre de cela? Cela vous apprendrait-il à mieux écrire en C ++? Peut-être. Mais très probablement, cela vous apprendrait simplement que & "C ++ est nul"! Cela vous apprendrait-il à utiliser le STL? Définitivement pas. Une approche plus utile pourrait utiliser l’impressionnant pouvoir de StackOverflow pour apprendre le STL correctement. :)

Autres conseils

Inconvénient: personne d'autre que vous ne l'utiliserez.

Avantage: Lors de sa mise en œuvre, vous apprendrez pourquoi la bibliothèque standard est une bonne chose.

Avantages: manger ses propres aliments pour chiens. Vous obtenez exactement ce que vous faites.

Inconvénients: manger ses propres aliments pour chiens. De nombreuses personnes, plus intelligentes que 99% d'entre nous, ont passé des années à créer le STL.

Je vous ai suggéré d'apprendre pourquoi:

  

en utilisant la STL crache des tonnes de   compilateur incompréhensible et mutilé   erreurs

premier

Inconvénient: vous passerez peut-être plus de temps à déboguer votre bibliothèque de classe qu'à la résolution de la tâche universitaire que vous avez devant vous.

Avantage: vous êtes susceptible d'apprendre beaucoup!

Vous pouvez faire quelque chose à propos des messages d'erreur STL du compilateur crypté. STLFilt aidera à les simplifier. Sur le site Web STLFilt :

  

STLFilt simplifie et / ou reformate   longue erreur C ++ et avertissement   messages, en mettant l’accent sur les problèmes liés au TSL   diagnostics (et pour MSVC 6, il est complètement   élimine les avertissements C4786 et leurs   détritus). Le résultat rend beaucoup de   même les diagnostics les plus cryptés   compréhensible.

Regardez ici et, si vous utilisez VisualC, également ici .

Je pense que vous devriez le faire.

Je suis sûr que je vais être flambé pour cela, mais vous savez, chaque programmeur C ++ ici a bu un peu trop de coolaid STL.

La STL est une excellente bibliothèque, mais je sais par expérience que si vous lancez la vôtre, vous pouvez:

1) Faites-le plus rapidement que la STL pour vos cas d'utilisation particuliers. 2) Vous allez écrire une bibliothèque avec juste les interfaces dont vous avez besoin. 3) Vous serez en mesure d'étendre tous les trucs standard. (Je ne peux pas vous dire combien j'ai souhaité que std :: string ait une méthode split ()) ...

Tout le monde a raison de dire que ce sera beaucoup de travail. C’est vrai.

Mais vous apprendrez beaucoup. Même si, une fois que vous l'avez écrit, vous retournez à la STL et vous ne l'utilisez plus, vous aurez quand même beaucoup appris.

Inconvénient: à mon humble avis, réimplémenter des bibliothèques testées et éprouvées est un véritable trou pour les lapins qui est presque garanti, ce qui en fait presque plus que la peine.

Un peu de mon expérience: Il n’ya pas si longtemps, j’ai mis en place ma propre classe semblable à un vecteur car j’avais besoin d’un bon contrôle.

Comme j'avais besoin de généricité, j'ai créé un tableau basé sur des modèles.

Je voulais aussi itérer à travers lui, pas en utilisant l'opérateur [] mais en incrémentant un pointeur comme si c'était le cas avec C, je ne calcule donc pas l'adresse de T [i] à chaque itération ... J'ai ajouté deux méthodes: une pour retourner le pointeur à la mémoire allouée et un autre qui retourne un pointeur à la fin. Pour parcourir un tableau d’entiers, j’ai dû écrire quelque chose comme ceci:

for(int * p = array.pData(); p != array.pEnd(); ++p){
  cout<<*p<<endl; 
}

Puis, lorsque je commence à utiliser des vecteurs de vecteurs, je me rends compte que s’il était possible, un utilisateur pouvait allouer un grand bloc de mémoire au lieu d’appeler plusieurs fois. A ce stade, j'ajoute un allocateur à la classe de modèle.

Ce n’est qu’alors que je remarque que j’ai écrit un clone parfaitement inutile de std :: vector < > ;.

Au moins, je sais maintenant pourquoi j'utilise STL ...

Autre inconvénient :

Si vous souhaitez obtenir un emploi en C ++ lorsque vous avez terminé vos études universitaires, la plupart des personnes qui souhaiteraient vous recruter s'attendent à ce que vous connaissiez bien la bibliothèque Standard C ++. Pas nécessairement intimement familier au niveau de la mise en œuvre mais certainement familier avec son utilisation et ses idiomes. Si vous réimpliquez la roue sous la forme de votre propre bibliothèque, vous manquerez votre chance. C’est nonobstant le fait que, espérons-le, vous en apprendrez beaucoup sur la conception des bibliothèques si vous lancez la vôtre, ce qui pourrait vous rapporter quelques points supplémentaires en fonction de l'endroit où vous interviewez.

Inconvénient:

Vous introduisez une dépendance à votre propre nouvelle bibliothèque. Même si cela suffit et que votre implémentation fonctionne bien, vous avez toujours une dépendance. Et cela peut vous mordre fort avec la maintenance du code. Tout le monde (y compris vous-même, dans un an ou même dans un mois) ne sera pas familiarisé avec votre comportement de chaîne unique, avec ses itérateurs spéciaux, etc. Il vous faudra beaucoup d'efforts pour vous adapter au nouvel environnement avant de pouvoir commencer à refactoriser / étendre quoi que ce soit. Si vous utilisez quelque chose comme STL, tout le monde le saura déjà, il sera bien compris et documenté, et personne ne devra réapprendre votre environnement personnalisé jetable.

Vous pourriez être intéressé par EASTL , une réécriture du STL Electronic Arts documentée il y a quelque temps. Leurs décisions de conception étaient principalement dictées par les désirs / besoins spécifiques de la programmation de jeux vidéo multiplateformes. Le résumé de l'article lié le résume bien.

Inconvénient: votre cours universitaire est probablement aménagé ainsi pour une raison. Le fait que vous soyez assez énervé par le sarcasme (sarcasme non voulu) peut indiquer que vous ne recevez pas le paridigme et qu'il vous sera très utile si vous changez de paradigme.

Avantages

Si vous examinez MFC, vous constaterez que votre suggestion est déjà utilisée dans un code productif - et ce depuis longtemps. Aucune des classes de collection de MFC n'utilise la STL.

Pourquoi ne regardez-vous pas les bibliothèques C ++ existantes? À l'époque où C ++ n'était pas aussi mature, les gens écrivaient souvent leurs propres bibliothèques. Jetez un coup d'œil à Symbian (assez horrible quand même), Qt et WxWidgets (si ma mémoire est bonne) ont des collections de base, etc., et il y en a probablement beaucoup d'autres.

Mon avis est que la complexité de STL découle de la complexité du langage C ++ et que vous ne pouvez rien faire pour l'améliorer (à part l'utilisation d'une convention de nommage plus raisonnable). Je vous recommande simplement de changer de langue si vous le pouvez, ou si vous vous en contentez.

  

Par exemple, l'utilisation de la STL crache   des tonnes d'incompréhensibles et mutilés   erreurs de compilation

La raison en est essentiellement des modèles C ++. Si vous utilisez des modèles (comme le fait STL), vous obtiendrez de nombreuses sources de messages d'erreur incompréhensibles . Donc, si vous implémentez vos propres classes de collection basées sur des modèles, vous ne serez pas mieux placé.

Vous pouvez créer des conteneurs non basés sur des modèles et tout stocker en tant que pointeurs vides ou en tant que classe de base, par exemple. Mais vous perdriez les vérifications de type de temps de compilation et le C ++ serait un langage dynamique. Il n’est pas aussi sûr de le faire que ce serait le cas, par exemple. Objective-C, Python ou Java. L'une des raisons est que C ++ ne possède pas de classe racine pour toutes les classes, ni d'introspection sur tous les objets, ni de gestion d'erreur de base lors de l'exécution. Au lieu de cela, votre application planterait et brûlerait probablement si vous vous trompiez de type et vous ne recevrez aucun indice sur ce qui ne va pas.

Inconvénient : la réimplémentation de tous de ce bien (c'est-à-dire, à un niveau de qualité élevé) nécessitera certainement de nombreux développeurs géniaux quelques années.

  

quels sont les dangers, les inconvénients et les avantages possibles de & "lancer mon propre &"; pour la plupart des fonctionnalités existantes en C ++?

Pouvez-vous vous permettre et éventuellement justifier l’effort / temps / argent consacré à la réinvention de la roue?

  

Réutiliser boost ou similaire.

Plutôt étrange que vous ne puissiez pas utiliser Boost. IIRC, des morceaux de contribution proviennent de personnes liées à / travaillant dans les universités (pensez à Jakko Jarvi). Les avantages de l’utilisation de Boost sont beaucoup trop nombreux pour être énumérés ici.

  

Ne pas "réinventer la roue"

Inconvénient: Si vous en apprenez beaucoup, vous vous repoussez également lorsque vous réfléchissez aux objectifs de votre projet.

Avantage: La maintenance est plus facile pour les personnes qui vont en hériter.

STL est très complexe car il doit s'agir d'une bibliothèque à usage général.

Raisons pour lesquelles STL est comme ça:

  • Basé sur les interators, les algorithmes standard n'ont besoin que d'une seule implémentation pour différents types de conteneurs.
  • Conçu pour se comporter correctement face aux exceptions.
  • Conçu pour être «thread» en sécurité dans les applications multithreads.

Dans de nombreuses applications, toutefois, vous en avez assez avec les éléments suivants:

  • classe de chaîne
  • table de hachage pour les recherches O (1)
  • vecteur / tableau avec tri / et recherche binaire des collections triées

Si vous savez cela:

  • Vos classes ne lèvent pas d'exceptions lors de la construction ou de l'affectation.
  • Votre code est à thread unique.
  • Vous n'utiliserez pas les algorithmes STL plus complexes.

Ensuite, vous pouvez probablement écrire votre propre code plus rapide qui utilise moins de mémoire et produit des erreurs de compilation / exécution plus simples.

Quelques exemples pour plus rapide / plus facile sans STL:

  • Chaîne de copie sur écriture avec tampon de référence de chaîne comptée. (Ne le faites pas dans un environnement multi-thread car vous auriez besoin de verrouiller l'accès au compte de références.)
  • Utilisez une bonne table de hachage au lieu des std :: set et std :: map.
  • Itérateurs de style 'Java' pouvant être transmis comme un seul objet
  • Type d'itérateur qui n'a pas besoin de connaître le type du conteneur (pour un meilleur découplage du code lors de la compilation)
  • Une classe de chaînes avec plus de fonctions utilitaires
  • Des limites configurables vérifiant vos conteneurs de vecteurs. (Donc, pas [] ou .at, mais la même méthode avec un indicateur de compilation ou d’exécution permettant de passer du mode 'sécurisé' au mode 'rapide')
  • Les conteneurs conçus pour fonctionner avec des pointeurs sur des objets qui vont supprimer leur contenu.

Il semble que vous ayez mis à jour la question. Il y a donc réellement deux questions:

  1. Que dois-je faire si je pense que la bibliothèque std :: library est trop complexe pour mes besoins?

Concevez vos propres classes qui utilisent en interne les fonctionnalités pertinentes de std :: library pour effectuer le & "; lever de lourdes charges &"; pour vous. De cette façon, vous aurez moins de mal à vous tromper et vous aurez toujours la possibilité d’inventer votre propre interface de codage.

  1. Que dois-je faire si je veux savoir comment fonctionnent les structures de données?

Concevez votre propre ensemble de classes de structures de données à partir de la base. Ensuite, essayez de comprendre pourquoi les standards sont meilleurs.

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