¿C ++ no es adecuado para OOP? [cerrado]

12

Leí en alguna parte de una de las respuestas a una pregunta aquí (no recuerdo cuál) que C ++ no es adecuado para la programación orientada a objetos. Se mencionó que podría hacer uso de su función o algo así, pero no en un sentido puramente orientado a objetos (en realidad no entendí lo que la persona quería decir).

¿Hay algo de verdad en esto? Si es así, ¿por qué?

gablin
fuente
55
OOP no es un término bien definido, por lo que discutir si C ++ es o no adecuado no tiene sentido.
zvrba

Respuestas:

31

Como se describe en Entonces, ¿qué * Alan * realmente quiso decir con el término "orientado a objetos"? , Alan Kay pensó que pasar mensajes era la parte importante de la POO, pero es la parte de la que carece "C con clases" (que luego se convirtió en C ++). C ++ es simplemente estructuras con un poco de comportamiento, mientras que los objetos en Smalltalk o Objective-C son "inteligentes" en el sentido de que pueden decidir qué hacer con los mensajes que se envían. Si un objeto Smalltalk-esque recibe un mensaje para el que no tiene una implementación, podría agregar perezosamente uno, reenviar el mensaje a otro objeto o hacer algo arbitrario.

Lo que C ++ ofrece en cuanto a la orientación a objetos son virtualmétodos y polimorfismos que involucran la forma en que se invocan esos métodos. Cuando el compilador ve un tipo de datos (o class) que tiene métodos virtuales, construye una vtable con una ranura para cada método virtual. Las subclases que implementan los métodos virtuales colocarán sus implementaciones en las ranuras correctas, por lo que el código del cliente simplemente necesita saber en qué parte de la tabla virtual buscar el código para ejecutarlo en lugar de resolverlo hasta la función específica. Lo que esto significa es que C ++ efectivamente lo hace tener un formulario de envío múltiple, a pesar de que todo está implementado en el compilador y no es tan capaz como un sistema Smalltalk-esque.

Si considera que el paso de mensajes es fundamental para OOP, si bien puede hacerlo con C ++, no es nada fácil. OTOH si considera que OOP significa asociar datos con funciones que actúan sobre esos datos, C ++ está bien.

Comunidad
fuente
8
+1 - pero siempre pensé que una llamada de función era una forma razonable de pasar un mensaje de todos modos. Es cierto que es una base de bajo nivel, en lugar de una solución de alto nivel para todo, pero el patrón de objetos activos muestra que es posible construir a partir de esa base.
Steve314
66
así que esto se aplica no solo a C ++, sino también a Java, C #, Object Pascal, etc. Y termina siendo que el sistema de mensajería API de Windows es lo que Alan quiso decir como lo más importante en OOP, especialmente la forma en que lo maneja Delphi
Trinidad
@trinidad correcto, excepto que C # realmente admite resolución dinámica. Espero que sea justo decir que nuestra idea de OOP ha cambiado con el tiempo para evitar la falta de transmisión de mensajes. Ayudado sin duda por los vendedores que dicen que su tecnología es definitivamente POO a la vista de la evidencia ...
@ steve314 sí lo es. De hecho, así es como funciona ObjC, un envío de mensaje se traduce en una llamada a la función que busca y llama a la función del método. Según entiendo el paso de mensajes, es importante el doble despacho.
1
@Paul: Tener una experiencia limitada con la API Win32, no entiendo. Cualquier API donde los objetos son de tamaño variable y donde es necesario llamar primero a una rutina para determinar qué tan grande será el objeto, asignar memoria y volver a llamarlo, falla mi prueba de belleza.
David Thornley
27

Este tipo de discusión me molesta porque suena a exégesis, a personas que debaten el significado de Holy Scriptute, o la Constitución estadounidense, y lo que los autores originales querían decir, como si lo que pensamos no importa.

Mire, Alan Kay era / es un tipo inteligente, y tuvo una buena idea, que se comparó con un montón de otras buenas ideas, y encontró su realización en Smalltalk y otros idiomas.

Él no es el Mesías, y OOP no es el verdadero paradigma de programación.

Es una buena idea, entre muchas. ¿C ++ tiene buenas ideas, provenientes de la mentalidad OOP? Claro que lo hace.

Mike Dunlavey
fuente
8

C ++ admite OOP, si define OOP para significar encapsulación, herencia y polimorfismo.

Sin embargo, C ++ realmente no sobresale en OOP. Una razón es que el polimorfismo a menudo depende de objetos asignados en el montón, que, a pesar del uso de punteros inteligentes, son más naturales para trabajar en un lenguaje recolectado de basura.

Donde C ++ sobresale, sin embargo, es en la programación genérica. C ++ le permite crear fácilmente código genérico altamente eficiente a través de técnicas de programación funcional basadas en plantillas.

Charles Salvia
fuente
4

C ++ prestó características de OOP de Simula. Uno o más de los desarrolladores de Simula IIRC comentaron que C ++ no es lo que tenían en mente.

C ++ tiene buenas herramientas para la abstracción, pero es más un lenguaje de paradigma mixto que un lenguaje orientado a objetos. Las funciones orientadas a objetos están ahí, pero tiene opciones que no son "estrictas POO".

Una de las traviesas "opciones de exclusión" que obtienes en C ++ es usar el enlace temprano en lugar de tarde para los métodos. Esto no solo es posible, es el valor predeterminado. En Java, "final" está relacionado, pero más limpio de alguna manera (que especifica la intención de una manera que no se trata sólo de evitar una sobrecarga de rendimiento trivial), y es no el valor predeterminado.

De alguna manera, C ++ muestra signos de ser un experimento temprano que todavía está aquí. Aun así, sigue siendo una buena herramienta, con muchas ventajas que no obtienes en otros lenguajes OOP.

Steve314
fuente
2
C ++ permite OOP y C ++ permite OOP, para que algún lenguaje sea OO tiene que permitir OOP, por lo tanto, C ++ es un lenguaje OO.
Trinidad
1
Creo que Alan Kay, de la fama Smalltalk, dijo que C ++ no era lo que tenía en mente cuando acuñó el término "orientado a objetos". Dado que C ++ comenzó como "C con clases", un injerto de clases Simula en C, y nunca hizo un corte limpio, no es de extrañar que parezca un experimento inicial.
David Thornley
1
@Trinidad: CUALQUIER lenguaje permite POO. He visto un montón de código OO agradable en el viejo y simple C. Sí, es difícil definir a mano todas las tablas de métodos virtuales, pero el lenguaje claramente lo permite .
Jan Hudec
4

Forzar que todo forme parte de una clase no necesariamente genera un excelente código OO.

Pídale a un programador de procedimientos pobre que programe en Java y posiblemente tomarán una clase en alguna parte, le darán un método principal estático y le pegarán 1000 líneas de código. Sé que lo he visto.

Java tiene una declaración de cambio. He visto switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }etc. en código C ++ y Java.

C ++ admite muchos conceptos de OO, pero su estándar no está definido por él, sin embargo, supongo que mucho depende de cuál sea su objetivo.

La principal semántica "pobre" en C ++ es permitir la construcción de copias de clases mediante las cuales un objeto se transfigura en otro. Puede deshabilitar esto pero luego no puede devolver uno de una función. Afortunadamente, esto se aborda en C ++ 0x.

CashCow
fuente
3

OOP no se trata solo de asegurarse de que todo sea o esté en una clase. Es perfectamente posible escribir código no OO en un lenguaje "puramente OO". Por ejemplo, "main" a menudo se señala como una función global, pero inventar una clase únicamente para contener un método main estático es igual que no OO.

C ++ funciona mejor con una mezcla de varias cosas; Esto no debería ser sorprendente, ya que así es como la mayoría de las cosas buenas funcionan mejor. A menudo, OOP es una de esas herramientas muy útiles.

Fred Nurk
fuente
2

C ++ se puede usar para OOP pero no es tan "puro" como algo como Smalltalk. C ++ también te permite hacer no OOP, que es de lo que la gente puede estar hablando.

Craig
fuente
2

Aunque no estoy de acuerdo con el sentimiento, es cierto que el sistema de tipos de C ++ no es pura OOP, no "todo es un objeto". Los números (en particular) no pueden extenderse tan fácilmente como pueden en, por ejemplo, Smalltalk. No puede redefinir el significado de "2 + 2", por ejemplo (aunque podría redefinir el significado de "dos + dos").

Pero lo que la mayoría de la gente probablemente quiere decir es que muchas personas escriben código no orientado a objetos en C ++ pero creen que debido a que están usando un lenguaje "OOP", están orientadas a objetos. Eso no es cierto. Pero en mi opinión, puede escribir código imperativo horrible en Smalltalk y no ser superior a un diseño OOP decente en C ++.

Larry OBrien
fuente
1

La objeción perfectamente válida de Alan Kay a C ++ fue que era un lenguaje macro encima de C.

La noción de "paso de mensajes" es simplemente la idea de que las instancias de clases se guardan en la memoria y que exponen métodos a los que se puede llamar. El paso de mensajes es * simulado "en C ++ usando vtables que contienen punteros a funciones.

Decir que el paso de mensajes no existe en C ++ es inexacto, lo que es más exacto decir es que el paso de mensajes es una parte integral de otros lenguajes como smalltalk y Java porque el lenguaje no está preprocesando una construcción extraña e injertándola en C directamente.

Este es un argumento de diseño de lenguaje altamente semántico que sospecho que está un poco más allá del nivel de experiencia del interrogador.

Dicho esto, hay miles de razones para odiar a C ++, y muy pocas razones para amarlo.

En lugar de buscar el martillo perfecto y el clavo perfecto, encuentre la casa perfecta para construir y luego encuentre las herramientas adecuadas ... eso requiere experiencia.

También es importante recordar que, en la programación de sistemas, lo que Alan Kay teme no es "pura POO", en realidad es una fortaleza de C ++. A cada uno lo suyo...

bobx
fuente
1
El objetivo C también comenzó como lenguaje macro encima de C, pero es un lenguaje orientado a objetos.
Jan Hudec
1

En mi opinión, no es tanto un problema de definición como un problema de usabilidad.

Los objetos son una abstracción destinada a facilitar la lectura, escritura y razonamiento sobre programas complejos. Para un programador práctico, si un lenguaje cumple con todos los criterios de una definición formal particular de "orientado a objetos" (¡parece que hay varios competidores!) No es realmente tan importante como si las herramientas que ofrece son adecuadas para pensar su programa en términos de dichos objetos, es decir, cosechar los supuestos beneficios de productividad de OOP.

En C ++, los objetos son abstracciones con fugas terribles , que a menudo obligan a los programadores a lidiar con problemas desagradables relacionados con la forma en que esos objetos están estructurados en la memoria, problemas que recuerdan más la codificación en C directo que otros lenguajes OOP. Por ejemplo, C ++ Respuestas a preguntas frecuentes ofrece esta crítica (entre otras):

Es muy beneficioso para un profesional familiarizarse con los sistemas OO que no sean C ++, y con las definiciones OO que no sean la trinidad de "encapsulación, herencia, polimorfismo" interpretada de maneras especiales que permitan que C ++ se considere "OO". Por ejemplo, una afirmación de que un entorno que carece de verificación de límites o recolección de basura no es un entorno OO parece indignante para las personas acostumbradas a C ++. Pero desde muchas perspectivas, tiene mucho sentido. Si alguien puede sobrescribir un objeto, ¿dónde está la "encapsulación"? Si desechar un objeto puede provocar referencias colgantes o pérdidas de memoria, ¿cómo está el sistema "orientado a objetos"? ? ¿Qué pasa con la capacidad de saber qué tipo de objeto se encuentra en un lugar y hora determinados? Dices que el software funciona con objetos, ¿dónde están? Y si uno no puede averiguarlo, ¿cómo se supone que se debe depurar el software?

C ++ está orientado a objetos, pero de manera desagradable e incompleta: sus usuarios tienen que dedicar mucho esfuerzo para asegurarse de que sus datos realmente se comporten como objetos "reales" en lugar de bits errantes. Dicho esto, se ha escrito mucho código en C ++ a lo largo de su vida útil, la mayor parte haciendo uso de clases y despacho dinámico, por lo que es evidentemente algo que puede usar para la OOP práctica.

Alex P
fuente
-1 para hacer referencia a la FQA en lo que debería ser una respuesta seria. El FQA es un nido de distorsiones, medias verdades y malentendidos.
David Thornley
@DavidThornley ¿Es la cita particular una distorsión, una verdad a medias o un malentendido?
Alex P
En algún lugar allí. La afirmación de que un lenguaje OO debe tener una verificación de límites (a veces integrada en los contenedores estándar de C ++ de todos modos) y la recolección de basura (los punteros inteligentes son la recolección de basura primitiva) es forzada y falsa. La oración acerca de un lenguaje que permite referencias colgantes que no están orientadas a objetos es claramente una prueba de Blatant Assertion. Me intriga la "capacidad de decir qué tipo de objeto"; el tipo de puntero lo entrega para objetos sin comportamiento virtual, y RTTI lo maneja para objetos con comportamiento virtual.
David Thornley
@DavidThornley La afirmación de la FQA es que un lenguaje OO útil debería tener estas cosas, lo que está en línea con la pregunta que se hace (¿C ++ es "adecuado"?). Creo que una afirmación sobre las definiciones básicas no aborda realmente eso ... "Capacidad para saber": un comportamiento de error común al acceder a un objeto que realmente no está allí, siguiendo un puntero a algunos datos no inicializados o sobrescritos previamente; y su programa felizmente tomará esa basura e interpretará como datos, y luego seguirá los punteros de basura a otros datos basura hasta que llegue a una dirección fuera de los límites o se produzca algún error masivo.
Alex P
Sin embargo, la cita al menos sugiere fuertemente la afirmación de que un lenguaje sin verificación de límites o recolección de basura no es OO, e ignoró el hecho de que tiene esas cosas en C ++ si lo desea. La cuestión de si un lenguaje evita o no ciertas clases de errores (por cualquier razón) es ortogonal a si es OO.
David Thornley
-1

Hay una razón por la que Graham Lee tuvo la mayor cantidad de votos aquí. Para reiterar, parece que una clase de C ++ no es realmente un objeto en el sentido de que no realiza el paso de mensajes. Creo que esto es lo que hace que la gente tropiece mucho cuando aprenden C ++ o oop. A las personas se les dice que la orientación a objetos es 'esto' y luego se les dice que C ++ lo hace de manera diferente. Bueno, C ++ nunca hizo POO de manera diferente. Si piensa de esta manera, nunca apreciará las clases de C ++ por lo que están destinadas y eso es que son simplemente una mejora del paradigma de procedimiento al incorporar abstracción y comportamiento dinámico. Por lo tanto, las clases de C ++ son de procedimiento fundamental, solo mejoran el paradigma de procedimiento o, más bien, son una versión más avanzada de una estructura de C.

molesto_quid
fuente
¿Tiene alguna razón de apoyo real para sus argumentos? Parece que está haciendo afirmaciones y afirmando que aquellos que no están de acuerdo deben estar equivocados, o cambiarían de opinión si lo miraran de manera diferente, o tal vez si compartieran su definición exacta de OO.
David Thornley
Lo suficientemente justo. Puedes leer este artículo . Supongo que lo que estaba diciendo es que c ++ no es "programación orientada a objetos" en un sentido estricto de Alan Kay. Sin embargo, si define OOP como una estructura de datos con comportamiento, entonces puede considerar c ++ como OOP. En mi opinión, sin embargo, es más preciso ver una clase de C ++ como una abstracción de programación de procedimientos de nivel superior. Una clase c ++ es mucho más eficiente que un objeto de estilo Kay, pero peor para la concurrencia. Personalmente, creo que la clase c ++ es un gran diseño.
annoying_squid
1
Gracias por el enlace, pero solo explica a qué se refería Alan Kay. Además, no estoy de acuerdo con que Smalltalk se considere generalmente el primer idioma OO, y Wikipedia está de acuerdo conmigo en que ese fue Simula, uno de los dos idiomas que Stroustrup combinó para formar C con las clases. Estoy interesado en su afirmación de que una clase C ++ es más una abstracción de programación de procedimientos de nivel superior que una plantilla de objeto, pero todavía no entiendo por qué piensa de esa manera.
David Thornley
La orientación a objetos es probablemente un término subjetivo, si podemos estar de acuerdo en eso. Pero veo un objeto Kay como una forma más natural de desacoplar código e introducir una modularidad concurrente en el sentido de que cada objeto cumple una función como las mini computadoras que interactúan a través del paso de mensajes. Según este modelo, debe haber poco o ningún código 'entre' b / c; toda la lógica del programa puede expresarse como celdas y mensajes. En comparación, el uso de 'clases' generalmente requiere un código de pegamento de procedimiento intermedio (carece de una verdadera modularidad), pero la ventaja es que las clases son mucho más eficientes.
annoying_squid
-1

Steve Yegge lo dijo mejor :

C ++ es el lenguaje más tonto de la tierra, en el sentido muy real de ser el menos sensible. No sabe de sí mismo.

El sistema de objetos en C ++ está tan cableado y fijo en el momento de la compilación, que está muy alejado de la noción original de OOP que implica el paso de mensajes, la introspección, la reflexión, el despacho dinámico y el enlace tardío, entre otras cosas. Lo único que C ++ y Smalltalk tienen en común es un poco de vocabulario.

John Cromartie
fuente
¿De qué manera es C ++ el lenguaje menos sensible? ¿Qué significa que un idioma sea sensible? Si quiere decir que carece de capacidades de reflexión, eso es bastante común, y ciertamente no elige a C ++ de la multitud.
David Thornley
2
¿Cómo puedes decir que lo dijo "mejor"? No tengo idea de lo que significa esa cita aleatoria.
user16764
Hacer +1 diciendo que este tipo de cosas tendrá muchas críticas por parte de los bashers de C ++, pero hay que decirlo: realmente no puedes OOP sin reflexión, porque no tienes los genéricos para ocuparte de cosas horizontales ( aspectos) - ciclo de vida (activación, eliminación), manejo de errores genéricos, proxy genérico, serialización genérica, paralelismo genérico de tareas - estos terminan contaminando su código y rompiendo el SoC.
vski
Gracias. No puedo creer que llegué a -3 por decir que un lenguaje sin reflexión no es un buen ejemplo de OOP.
John Cromartie
1
@ JohnCromartie, ¿Podrías dar más detalles sobre ese punto en tu respuesta?
Jeremy Heiler