Hay varios patrones de diseño como Adaptador, Iterador implementado en STL.
¿Eso significa que STL se implementa con conceptos OO?
¿Cuál es la relación entre OO y las partes de plantilla de C ++?
Aprendí que la función de miembro virtual que justifica el OO está en contradicción con la plantilla, ¿es esto correcto?
Respuestas:
Primero, "STL" no es un término oficial, es el nombre de la biblioteca propuesta para incluir en la Biblioteca Estándar de C ++ cuando no había contenedores. Proporciona esencialmente plantillas de contenedor y algoritmos.
Ahora, estas plantillas de contenedor y algoritmos son ... plantillas, por lo que producen tipos según sea necesario. No se basan en la herencia desde el punto de vista del usuario.
Sin embargo, la biblioteca estándar especifica esencialmente la interfaz de la biblioteca, no la implementación. Muchas implementaciones de STL utilizarán un poco de orientación a objetos en su implementación, pero como usuario no lo verá si no se sumerge en el código fuente de sus implementaciones (que deben exponerse ya que es esencialmente un código de plantilla).
No, son conceptos ortogonales que proporcionan conjuntos muy diferentes de ventajas y desventajas. De hecho, en C ++, una de las principales ventajas de usar dicho lenguaje es que tiene ambos disponibles y el uso de uno no cancela el uso del otro. Incluso es una gran ventaja. Por ejemplo, uno de los modismos más interesantes en C ++ es CRTP que usa tanto plantillas como herencia. La idea es que la parte de herencia le permite extender varios tipos con un comportamiento y datos comunes, como una clase base; mientras que la parte de la plantilla se asegura de generar clases base específicas para cada niño, haciendo imposible tener un puntero a todas las clases usando la clase CRTP como base. Esto es extremadamente útil y no permite jugar con la herencia donde no debería haberla.
También he implementado sistemas de distribución de eventos muy genéricos que no conocían los tipos de eventos ni los tipos de escucha, pero combinaron código interno dinámico y estático que juntos permitieron generar los tipos internos correctos correspondientes a los tipos de tiempo de ejecución correctos.
Y ese es el punto: no siempre se necesita "orientación a objetos". De hecho, la mayoría de las veces no lo necesita en absoluto, necesita definir algunos tipos y usarlos directamente como parte diferente de algún tipo de motor abstracto (composición). No siempre necesita un código genérico, también conocido como plantillas. A veces lo necesita para generalizar una función que se aplica a varios tipos no relacionados. Cuando están relacionados, puede usar su clase base y no necesitar plantillas.
Tienen diferentes ventajas y costos completamente diferentes, por lo que son buenos para combinar para resolver problemas complejos.
STL es un buen ejemplo de un problema en el que la mayor parte se trata de proporcionar tipos (contenedores) y funciones (algoritmos) que están relacionados con un tipo determinado en lugar de una jerarquía de objetos de tiempo de ejecución. En la biblioteca estándar, los flujos se hacen de una manera típica de la orientación a objetos: es una jerarquía de clases de flujo que hace cosas diferentes de una manera que permite definir una clase de flujo secundario que combina diferentes comportamientos / capacidades. Allí, la orientación a objetos es útil, incluso si algunas personas prefieren que se parezca más al STL (no soy un especialista en el tema).
Entonces, piense en ellas como herramientas muy diferentes, como un destornillador y un martillo. C ++ no te deja pensar con solo una herramienta en mente.
fuente
En realidad, el STL introdujo el paradigma de programación genérica en la corriente principal.
Cuando me enseñaron el paradigma de Programación Orientada a Objetos (por algún profesor) hace 15 años, me enseñaron que los tres pilares cruciales son la encapsulación, la herencia y el polimorfismo (hoy este último probablemente debería calificarse como polimorfismo de tiempo de ejecución ), mientras que Wikipedia actualmente enumera la abstracción de datos, la encapsulación, la mensajería, la modularidad, el polimorfismo y la herencia como características definitorias de OOP. Por supuesto, el STL usa algunos de ellos, como la encapsulación, pero luego también usa funciones, que son una característica del paradigma de Programación Estructurada . Sin embargo, nadie diría que el STL es Programación Estructurada .
Tenga en cuenta que una de las características más potentes de C ++ es el hecho de que admite muchos paradigmas de programación (Estructurado, Orientado a objetos, Genérico, Programación funcional y otros) y que brilla más donde se mezclan y mezclan.
fuente
Para citar a Alexander Stepanov de su entrevista STLPort :
Dicho esto, se podría hacer una implementación individual utilizando la herencia y el polimorfismo en algunos lugares. Solo por ejemplo, he visto una implementación en la que
iterator
se derivóconst_iterator
para admitir la conversión implícita deiterator
aconst_iterator
. Sin embargo, la derivación no es característica o requerida por el diseño.En pocas palabras: si bien puede / podría usar código orientado a objetos para implementar algunas partes de la STL, el diseño de la propia STL no está (enfáticamente) orientado a objetos.
fuente
No, diría que el STL no es particularmente OO, en todo caso, se asigna más a un estilo de programación funcional. En particular:
Del mismo modo, puede argumentar que los contenedores son mónadas
vector<string>(1,"Foo")
Para sus otras preguntas, las partes OO y las partes de plantilla de C ++ están separadas y las funciones virtuales no impiden tener plantillas. En el caso de STL, el diseño simplemente no elige usar funciones virtuales.
fuente
std::vector<int>
no esté orientado a objetos.Depende de a quién le pida una definición de OOP, porque OOP es un término notoriamente mal definido y no hay un buen consenso sobre qué constituye OOP y qué no.
Desde la perspectiva de una persona Java, la respuesta es probablemente "no", ya que la biblioteca de algoritmos y contenedores de C ++ no se ocupa del polimorfismo en tiempo de ejecución, no usa la herencia de clases y porque la sintaxis no parece OOP-y.
Por otro lado, pregunte a una persona de programación funcional y la respuesta puede ser "sí".
Así es como Wikipedia define OOP:
Todos estos se realizan, o se ayudan, en la biblioteca estándar de C ++, y en particular en la parte que trata con contenedores y algoritmos. En particular, los algoritmos fortalecen la encapsulación y la abstracción (y, por lo tanto, la modularidad) y son polimorfos mediante el uso de plantillas.
fuente
En mi opinión, STL trata más sobre algoritmos sobre contenedores iterables que OO.
Define una interfaz común (el iterador) que se implementará para utilizar los algoritmos.
Los iteradores de C / C ++ se denominan enumerador / enumerable en Java y C #
Quizás STL está más orientado a aspectos que OO.
fuente
¿Dónde demonios escuchaste eso?
Los principios cruciales de la orientación a objetos son la encapsulación y la abstracción.
virtual
las funciones son solo un medio por el cual se logra eso. No son necesarios para la orientación real de los objetos. De hecho, una plantilla es un medio perfectamente adecuado. Puede que no sea herencia, pero sigue siendo una especie de polimorfismo. Y algunas clases no requieren ninguno.Los contenedores de la biblioteca estándar están absolutamente orientados a objetos. Encapsulan todos los detalles innecesarios de la interfaz y abstraen la implementación al máximo que sea razonablemente posible.
fuente
La implementación de OOP, por sí sola, no significa nada hasta que no defina lo que quiere decir con "objeto". Si los objetos son valores (no entidades, como la mayoría de los llamados lenguajes OOP pero C ++ asume), entonces STL es OOP, de lo contrario no.
Asuma este fragmento de código:
¿Son
a
yb
dos representaciones de una misma persona viva o solo dos pesonas vivas con el mismo nombre?¿Cuál es el objeto?
a
,b
O la persona viva (s) que representan?Además, la herencia de C ++ es un mecanismo de agregación técnica que es diferente de la herencia de objetos (que es una abstracción). Los dos pueden coincidir si impone una determinada disciplina (como los Objetos son accesibles a través de la indirecta y son reemplazables, lo que significa que todos los métodos relevantes son virtuales) de lo contrario pueden apuntar a objetivos diferentes (la herencia de C ++ no es más que una "composición implícita" )
Las plantillas también pueden (a través de la especialización) ofrecer un mecanismo de "sustitución", basado en tipos estáticos en lugar de tipos dinámicos (basados en funciones virtuales) y, en este sentido, si se utiliza una misma disciplina en tiempo de compilación, proporcionar una OOP en tiempo de compilación.
En esencia, ninguno de los esquemas de agregación y despacho de C ++ es por sí solo OOP o justifica OOP. También pueden hacer otras cosas. OOP es una metodología abstracta para describir y relacionar objetos juntos. Esas relaciones pueden asignarse a herencia y despacho virtual si los tipos de objeto dependen de la ejecución en tiempo de ejecución, o pueden asignarse a la especialización de plantilla y las conversiones implícitas si los tipos de objeto pueden definirse durante la compilación. La herencia puede ser solo una de las formas de proporcionar una conversión implícita entre referencias y punteros.
fuente