Le C ++ ne convient-il pas à la POO? [fermé]

12

J'ai lu quelque part dans l'une des réponses à une question ici (je ne me souviens pas laquelle) que C ++ n'est pas adapté à la programmation orientée objet. Certains ont mentionné que vous pouviez utiliser sa fonctionnalité ou quelque chose comme ça, mais pas dans un sens purement POO (en fait, je ne comprenais pas vraiment ce que la personne voulait dire).

Y a-t-il du vrai là-dedans? si oui, pourquoi?

gablin
la source
5
La POO n'est pas un terme bien défini, donc discuter si C ++ est ou n'est pas approprié est plutôt inutile.
zvrba

Réponses:

31

Comme décrit dans So what * did * Alan Kay voulait-il vraiment dire par le terme "orienté objet"? , Alan Kay pensait que la transmission de messages était l'élément le plus important de la POO, mais c'est l'élément qui manque au "C avec classes" (qui est devenu plus tard C ++). C ++ est juste des structures avec un peu de comportement, alors que les objets dans Smalltalk ou Objective-C sont "intelligents" en ce sens qu'ils peuvent décider de ce qu'ils font avec les messages qui leur sont envoyés. Si un objet Smalltalk-esque reçoit un message pour lequel il n'a pas d'implémentation, il peut en ajouter paresseusement, transmettre le message à un autre objet ou faire n'importe quelle chose arbitraire.

Ce que C ++ offre en termes d'orientation d'objet, ce sont les virtualméthodes et le polymorphisme impliquant la façon dont ces méthodes sont invoquées. Lorsque le compilateur voit un type de données (ou class) qui a des méthodes virtuelles, il construit une table virtuelle avec un emplacement pour chaque méthode virtuelle. Les sous-classes qui implémentent les méthodes virtuelles placent leurs implémentations dans les emplacements corrects, de sorte que le code client a simplement besoin de savoir où dans la table virtuelle chercher le code à exécuter plutôt que de le résoudre jusqu'à la fonction spécifique. Ce que cela signifie est que C ++ effectivement fait une forme d'envoi multiple, mais il est tout mis en œuvre dans le compilateur et ne sont pas aussi capables que d' un système Smalltalk-esque.

Si vous considérez que la transmission de messages est fondamentale pour la POO, alors que vous pouvez le faire avec C ++, ce n'est pas facile. OTOH si vous considérez OOP comme signifiant associer des données à des fonctions qui agissent sur ces données, C ++ est très bien.

Communauté
la source
8
+1 - mais j'ai toujours pensé qu'un appel de fonction était de toute façon un moyen raisonnable de transmettre un message. Certes, c'est une fondation de bas niveau, plutôt qu'un correctif de haut niveau pour tout - mais le modèle d'objets actifs montre qu'il est possible de construire à partir de cette fondation.
Steve314
6
donc cela vaut non seulement pour C ++, mais à Java, C #, Objet Pascal, etc. Et il finit par être ce système de messagerie API Windows est ce que Alan signifie que la chose la plus importante en POO, en particulier la façon dont il est géré par Delphi
Trinidad
@trinidad correct, sauf que C # prend en charge la résolution dynamique. Je pense qu'il est juste de dire que notre idée de la POO a changé au fil du temps pour contourner le manque de transmission de messages. Aidé sans aucun doute par les vendeurs disant que leur technologie est définitivement OOP face aux preuves ...
@ steve314 oui c'est le cas. En effet, c'est ainsi que fonctionne ObjC, un message envoyé est traduit en un appel de fonction qui recherche et appelle la fonction méthode. Si je comprends bien la transmission des messages, c'est la double répartition qui est importante.
1
@ Paul: Ayant une expérience limitée avec l'API Win32, je ne comprends pas. Toute API où les objets sont de taille variable et où il est nécessaire d'appeler d'abord une routine pour déterminer la taille de l'objet, d'allouer de la mémoire et de l'appeler à nouveau, échoue à mon test de beauté.
David Thornley
27

Ce genre de discussion me dérange parce que cela ressemble à de l'exégèse, à des gens qui débattent de la signification du Saint Scripture ou de la Constitution américaine, et de ce que les auteurs originaux voulaient dire, comme si ce que nous pensons n'avait pas d'importance.

Regardez, Alan Kay était / est un gars intelligent, et il a eu une bonne idée, qui a frotté contre un tas d'autres bonnes idées, et a trouvé sa réalisation dans Smalltalk et dans d'autres langues.

Il n'est pas le Messie et la POO n'est pas le seul vrai paradigme de programmation.

C'est une bonne idée, parmi beaucoup d'autres. Le C ++ contient-il de bonnes idées, issues de la mentalité OOP? Bien sûr que oui.

Mike Dunlavey
la source
8

C ++ prend en charge la POO, si vous définissez la POO comme signifiant l'encapsulation, l'héritage et le polymorphisme.

Cependant, C ++ n'excelle pas vraiment chez OOP. L'une des raisons est que le polymorphisme dépend souvent d'objets alloués en tas, qui, malgré l'utilisation de pointeurs intelligents, sont plus naturels à utiliser dans un langage récupéré.

Cependant, où C ++ excelle, c'est dans la programmation générique. C ++ vous permet de créer facilement du code générique hautement efficace grâce à des techniques de programmation fonctionnelle basées sur des modèles.

Charles Salvia
la source
4

Fonctionnalités OOP empruntées en C ++ à Simula. Un ou plusieurs développeurs de Simula IIRC ont déclaré que le C ++ n'était pas ce qu'ils avaient en tête.

C ++ a de bons outils pour l'abstraction, mais c'est plus un langage à paradigme mixte qu'un langage orienté objet. Les fonctionnalités orientées objet sont là, mais vous avez des choix qui ne sont pas "POO stricts".

L'un des "opt-outs" coquins que vous obtenez en C ++ est d'utiliser une liaison précoce plutôt que tardive pour les méthodes. Non seulement cela est possible - c'est la valeur par défaut. En Java, "final" est lié, mais plus propre à certains égards (il spécifie l'intention d'une manière qui ne consiste pas seulement à éviter une surcharge de performances triviale), et ce n'est pas la valeur par défaut.

À certains égards, C ++ montre des signes d'une première expérience qui est toujours là. Malgré tout, c'est toujours un bon outil, avec de nombreux avantages que vous n'obtenez pas dans d'autres langues OOP.

Steve314
la source
2
C ++ autorise les non-OOP et C ++ autorise les OOP, pour qu'un langage soit OO, il doit autoriser les OOP, donc C ++ est un langage OO.
Trinidad
1
Je crois qu'Alan Kay, de la renommée de Smalltalk, a déclaré que le C ++ n'était pas ce qu'il avait en tête lorsqu'il a inventé le terme "orienté objet". Depuis que C ++ a commencé comme "C with Classes", une greffe de classes Simula sur C, et n'a jamais fait de rupture nette, il n'est pas étonnant que cela ressemble à une première expérience.
David Thornley
1
@ Trinidad: N'IMPORTE QUELLE langue autorise la POO. J'ai vu pas mal de code OO sympa en simple vieux C. Oui, c'est difficile de définir toutes les tables de méthodes virtuelles à la main, mais le langage le permet clairement .
Jan Hudec
4

Forcer tout à faire partie d'une classe ne produit pas nécessairement un excellent code OO.

Demandez à un mauvais programmeur procédural de programmer en Java et ils prendront peut-être une classe quelque part, lui donneront une méthode principale statique et y colleront 1000 lignes de code. Je sais que je l'ai vu.

Java a une instruction switch. J'ai vu switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }etc. dans le code C ++ et Java.

C ++ prend en charge de nombreux concepts OO mais sa norme n'est pas définie par lui, mais je suppose que cela dépend beaucoup de votre objectif.

La principale sémantique «pauvre» en C ++ permet la construction de copies de classes par lesquelles un objet se transforme en un autre. Vous pouvez désactiver cela mais vous ne pouvez pas en renvoyer une à partir d'une fonction. Heureusement, cela est résolu en C ++ 0x.

Vache à lait
la source
3

La POO ne consiste pas seulement à s'assurer que tout est dans ou est dans une classe. Il est parfaitement possible d'écrire du code non OO dans un langage "purement OO". Par exemple, "main" est souvent indiqué comme étant une fonction globale, mais inventer une classe uniquement pour contenir une méthode principale statique est tout aussi non-OO.

C ++ fonctionne mieux avec un mélange de diverses choses; cela ne devrait pas être surprenant, car c'est ainsi que la plupart des bonnes choses fonctionnent le mieux. La POO est souvent l'un de ces outils très utiles.

Fred Nurk
la source
2

C ++ peut être utilisé pour la POO mais il n'est pas aussi «pur» que quelque chose comme Smalltalk. C ++ vous permet également de faire des non-OOP, ce dont les gens peuvent parler.

Craig
la source
2

Bien que je ne sois pas d'accord avec le sentiment, il est vrai que le système de type de C ++ n'est pas de la POO pure - pas "tout est un objet". Les nombres (en particulier) ne peuvent pas être étendus aussi facilement qu'ils le peuvent, par exemple, dans Smalltalk. Vous ne pouvez pas redéfinir la signification de "2 + 2" par exemple (bien que vous puissiez redéfinir la signification de "deux + deux").

Mais ce que la plupart des gens probablement moyen est que beaucoup de gens écrivent du code orienté non-objet en C ++ , mais croient que parce qu'ils utilisent une langue « POO », ils sont orientés objet. Ce n'est pas vrai. Mais à mon avis, vous pouvez écrire un code impératif hideux dans Smalltalk et ne pas être supérieur à une conception OOP décente en C ++.

Larry OBrien
la source
1

L'objection parfaitement valable d'Alan Kay au C ++ était qu'il s'agissait d'un macro langage en plus de C.

La notion de «passage de message» est simplement l'idée que les instances de classes sont conservées en mémoire et qu'elles exposent des méthodes qui peuvent être appelées. Le passage de message est * simulé "en C ++ en utilisant des tables vtables contenant des pointeurs vers des fonctions.

Dire que le passage de messages n'existe pas en C ++ est inexact, ce qui est plus précis à dire, c'est que le passage de messages fait partie intégrante d'autres langages comme smalltalk et Java car le langage ne pré-traite pas une construction étrangère et ne la greffe pas directement sur C.

Il s'agit d'un argument de conception de langage hautement sémantique qui, je le soupçonne, dépasse un peu le niveau d'expérience du questionneur.

Cela étant dit, il y a mille raisons de détester le C ++ et très peu de raisons de l'aimer.

Plutôt que de chercher le marteau parfait et l'ongle parfait, trouvez la maison parfaite à construire, puis trouvez les bons outils ... qui nécessitent de l'expérience.

Il est également important de se rappeler que dans la programmation système, ce qu'Alan Kay craint de ne pas être "pure POO" est en fait une force du C ++. À chacun ses goûts...

bobx
la source
1
Objective C a également commencé comme langage macro au-dessus de C, mais est un langage orienté objet.
Jan Hudec
1

À mon avis, ce n'est pas tant un problème de définition qu'un problème de convivialité.

Les objets sont une abstraction destinée à faciliter la lecture, l'écriture et le raisonnement sur les programmes complexes. Pour un programmeur pratique, le fait qu'un langage réponde à tous les critères d'une définition formelle particulière de "orienté objet" (il semble y en avoir plusieurs concurrents!) N'est pas vraiment aussi important que de savoir si les outils qu'il propose sont adaptés à la réflexion. votre programme en termes desdits objets - c'est-à-dire récolter les avantages supposés de productivité de la POO.

En C ++, les objets sont des abstractions terriblement fuyantes , obligeant souvent les programmeurs à se débattre avec des problèmes désagréables liés à la façon dont ces objets sont structurés en mémoire - des problèmes qui rappellent plus le codage en C droit que les autres langages OOP. Par exemple, C ++ Frequently Questioned Answers propose cette critique (entre autres):

Il est très bénéfique pour un praticien de se familiariser avec des systèmes OO autres que C ++, et avec des définitions OO autres que la trinité "encapsulation, héritage, polymorphisme" interprétée de manière spéciale permettant au C ++ d'être considéré comme "OO". Par exemple, une affirmation selon laquelle un environnement dépourvu de vérification des limites ou de collecte des ordures n'est pas un environnement OO semble scandaleuse pour les personnes habituées au C ++. Mais à bien des égards, cela a beaucoup de sens. Si quelqu'un peut écraser un objet, où est "l'encapsulation"? Si l'élimination d'un objet peut entraîner des références pendantes ou des fuites de mémoire, comment le système est-il "orienté objet" ? Qu'en est-il de la capacité de dire quel type d'objet se trouve à un endroit et à un moment donnés? Vous dites que le logiciel fonctionne avec des objets - où sont-ils? Et si l'on ne peut pas le savoir, comment est-il censé déboguer le logiciel?

Le C ++ est orienté objet, mais de manière désagréable et incomplète: ses utilisateurs doivent consacrer beaucoup d'efforts pour s'assurer que leurs données se comportent réellement comme des "vrais" objets plutôt que des bits errants. Cela dit, beaucoup de code a été écrit en C ++ au cours de sa durée de vie, la plupart utilisant des classes et une répartition dynamique, c'est donc évidemment quelque chose que vous pouvez utiliser pour la POO pratique.

Alex P
la source
-1 pour référencer le FQA dans ce qui devrait être une réponse sérieuse. Le FQA est un nid de distorsions, de demi-vérités et de malentendus.
David Thornley
@DavidThornley La citation particulière est-elle une distorsion, une demi-vérité ou un malentendu?
Alex P
Quelque part là-dedans. L'affirmation selon laquelle un langage OO doit avoir une vérification des limites (parfois intégrée dans les conteneurs standard C ++ de toute façon) et une récupération de place (les pointeurs intelligents sont une récupération de place primitive) est forcée et mensongère. La phrase sur un langage qui permet aux références pendantes qui ne sont pas orientées objet est clairement Proof by Blatant Assertion. Je suis perplexe devant la «capacité de dire quel genre d'objet»; le type de pointeur le donne pour les objets sans comportement virtuel et RTTI le gère pour les objets avec comportement virtuel.
David Thornley
@DavidThornley L'affirmation de la FQA est qu'un langage OO utile devrait avoir ces choses - ce qui est conforme à la question posée (le C ++ est-il "approprié"?). Je pense qu'une affirmation sur les définitions à nu ne résout pas vraiment cela ... "Capacité à dire": un comportement d'erreur courant accédant à un objet qui n'est pas vraiment là, en suivant un pointeur vers des données non initialisées ou écrasées précédemment; et votre programme se fera un plaisir de prendre ces ordures et de les interpréter comme des données, puis de suivre les pointeurs d'ordures vers d'autres données d'ordures jusqu'à ce qu'elles atteignent une adresse hors limites ou qu'une erreur massive se produise.
Alex P
Cependant, la citation suggère au moins fortement l'affirmation selon laquelle un langage sans vérification des limites ou garbage collection n'est pas OO, et ignore le fait que vous avez ces choses en C ++ si vous le souhaitez. La question de savoir si un langage empêche ou non certaines classes d'erreurs (pour quelque raison que ce soit) est orthogonale s'il s'agit d'OO.
David Thornley
-1

Il y a une raison pour laquelle Graham Lee a eu le plus de votes positifs ici. Pour réitérer, il apparaît qu'une classe C ++ n'est pas vraiment un objet dans le sens où elle n'effectue pas de passage de message. Je pense que c'est ce qui fait beaucoup voyager les gens lorsqu'ils apprennent le C ++ ou oop. On dit aux gens que l'objet est «ceci» et que le C ++ le fait différemment. Eh bien, C ++ n'a jamais fait la POO différemment. Si vous pensez de cette façon, vous n'apprécierez jamais les classes C ++ pour ce à quoi elles sont destinées et c'est qu'elles ne sont qu'une amélioration du paradigme procédural en incorporant l'abstraction et le comportement dynamique. Les classes C ++ sont donc fondamentalement procédurales, elles améliorent simplement le paradigme procédural, ou plutôt elles sont une version plus avancée d'une structure C.

annoying_squid
la source
Avez-vous des raisons réelles à l'appui de vos arguments? Vous semblez faire des affirmations et prétendre que ceux qui ne sont pas d'accord doivent se tromper, ou changeraient d'avis s'ils le considéraient différemment, ou peut-être s'ils partageaient votre définition exacte de l'OO.
David Thornley
C'est suffisant. Vous pouvez lire cet article . Je suppose que ce que je disais est que c ++ n'est pas une "programmation orientée objet" au sens strict d'Alan Kay. Cependant, si vous définissez OOP comme étant une structure de données avec un comportement, vous pouvez considérer c ++ comme OOP. Dans mon esprit, il est plus précis de voir une classe c ++ comme une abstraction de programmation procédurale de niveau supérieur. Une classe c ++ est beaucoup plus efficace qu'un objet de style Kay, mais pire pour la concurrence. Personnellement, je pense que la classe c ++ est un excellent design.
annoying_squid
1
Merci pour le lien, mais il explique seulement ce que voulait dire Alan Kay. De plus, je ne suis pas d'accord pour dire que Smalltalk est généralement considéré comme la première langue OO, et Wikipedia convient avec moi que c'était Simula, l'une des deux langues que Stroustrup a combinées pour former C avec Classes. Je suis intéressé par votre affirmation qu'une classe C ++ est plus une abstraction de programmation procédurale de niveau supérieur qu'un modèle d'objet, mais je ne comprends toujours pas pourquoi vous pensez de cette façon.
David Thornley
L'orientation d'objet est probablement un terme subjectif, si nous pouvons nous mettre d'accord là-dessus. Mais je vois un objet Kay comme un moyen plus naturel de découpler le code et d'introduire une modularité simultanée dans le sens où chaque objet joue un rôle comme des mini-ordinateurs interagissant via le passage de messages. Dans ce modèle, il doit y avoir peu ou pas de code «entre» b / c toute la logique du programme peut être exprimée sous forme de cellules et de messages. En comparaison, l'utilisation de «classes» nécessite généralement du code de procédure entre les deux (manque de véritable modularité) mais l'avantage est que les classes sont beaucoup plus efficaces.
annoying_squid
-1

Steve Yegge l'a dit le mieux :

Le C ++ est le langage le plus stupide au monde, au sens très réel d'être le moins sensible. Il ne se connaît pas.

Le système d'objets en C ++ est tellement câblé et fixé au moment de la compilation, qu'il est très éloigné de la notion originale de POO qui implique le passage de messages, l'introspection, la réflexion, la distribution dynamique et la liaison tardive, entre autres. La seule chose que C ++ et Smalltalk ont ​​en commun est un peu de vocabulaire.

John Cromartie
la source
En quoi le C ++ est-il le langage le moins sensible? Qu'est-ce que cela signifie pour une langue d'être sensible? Si vous voulez dire qu'il manque de capacités de réflexion, c'est assez courant et ne retire certainement pas le C ++ d'une foule.
David Thornley
2
Comment diable pouvez-vous dire qu'il l'a dit "mieux"? Je n'ai aucune idée de ce que signifie cette citation aléatoire.
user16764
+1 disant que ce genre de chose obtiendra beaucoup de flak des bashers C ++ basher, mais il faut le dire - vous ne pouvez pas vraiment OOP sans réflexion, parce que vous n'avez pas les génériques pour vous occuper des trucs horizontaux ( aspects) - cycle de vie (activation, élimination), gestion générique des erreurs, proxy générique, sérialisation générique, parallélisme générique des tâches - cela finit par polluer votre code et casser le SoC.
vski
Merci. Je ne peux pas croire que je suis arrivé à -3 pour avoir dit qu'un langage sans réflexion n'est pas un bon exemple de POO.
John Cromartie
1
@JohnCromartie, pourriez-vous développer ce point dans votre réponse?
Jeremy Heiler