¿Por qué C no se considera un lenguaje 'orientado a objetos'?

92

Parece que C tiene sus propios cuasi-objetos, como 'estructuras' que pueden considerarse como objetos (en la forma de alto nivel que normalmente pensaríamos).

Y también, los archivos C son básicamente "módulos" separados, ¿verdad? ¿Entonces los módulos no son como "objetos"? Estoy confundido acerca de por qué C, que parece tan similar a C ++, se considera un lenguaje "procesal" de bajo nivel donde C ++ es "orientado a objetos" de alto nivel

* editar: (aclaración) ¿por qué y dónde, se dibuja la línea, para qué es y qué no es un 'objeto'?

Templario oscuro
fuente
40
Todos, ¿por qué los votos negativos? Es una pregunta básica pero no mala.
Jon Hopkins
77
Puede usar los principios de OO de manera efectiva en C (y las personas que escriben un buen código de C generalmente lo hacen), pero el lenguaje no se basa en facilitarlo, como lo hacen muchos lenguajes más recientes.
asveikau
55
C simplemente tiene un enfoque diferente, más simple y (para ser sincero) mejor definido (al menos entre la comunidad de código abierto) para la abstracción de datos. C ++ tiende a ser un centro de abstracción y permite muchas cosas geniales, pero conlleva el costo de tener que entender cómo [no] usarlas correctamente, lo que, en la mayoría de los casos, no se encuentra en los programas comunes. Vea mi respuesta completa para más detalles.
Yam Marcovic
1
En breve: las estructuras no pueden tener métodos. (El puntero a una función no es suficiente).
SF.
1
Es posible hacer programación basada en objetos en C, con cierta dificultad. Pero eso no lo hace orientado a objetos .
Wedge

Respuestas:

101

Parece que C tiene sus propios cuasi-objetos como 'structs' que pueden considerarse como objetos

Juntos, usted y yo leemos la página de Wikipedia sobre programación orientada a objetos y marcamos las características de estructuras de estilo C que corresponden a lo que tradicionalmente se considera estilo orientado a objetos:

(OOP) es un paradigma de programación que utiliza "objetos": estructuras de datos que consisten en campos y métodos de datos junto con sus interacciones

¿Las estructuras C consisten en campos y métodos junto con sus interacciones ? No.

Las técnicas de programación pueden incluir características tales como abstracción de datos, encapsulación, mensajería, modularidad, polimorfismo y herencia.

¿Las estructuras C hacen alguna de estas cosas de manera "de primera clase"? No. El lenguaje funciona en tu contra en cada paso del camino.

El enfoque orientado a objetos alienta al programador a colocar datos donde el resto del programa no puede acceder directamente a ellos.

¿Las estructuras C hacen esto? No.

Un programa orientado a objetos generalmente contendrá diferentes tipos de objetos, cada tipo correspondiente a un tipo particular de datos complejos para ser administrados o quizás a un objeto o concepto del mundo real

¿Las estructuras C hacen esto? Si.

Se puede considerar que los objetos envuelven sus datos dentro de un conjunto de funciones diseñadas para garantizar que los datos se usen adecuadamente

No.

cada objeto es capaz de recibir mensajes, procesar datos y enviar mensajes a otros objetos

¿Puede una estructura misma enviar y recibir mensajes? No. ¿Puede procesar datos? No.

Las estructuras de datos OOP tienden a "llevar a sus propios operadores con ellos"

¿Esto sucede en C? No.

Despacho dinámico ... Encapsulación ... Polimorfismo de subtipo ... Herencia de objetos ... Recursión abierta ... Clases de objetos ... Instancias de clases ... Métodos que actúan sobre los objetos adjuntos ... Paso del mensaje ... Abstracción

¿Alguna de estas características de las estructuras C? No.

Precisamente, ¿qué características de las estructuras crees que están "orientadas a objetos"? Porque no puedo encontrar ninguna otra que el hecho de que estructuras definen tipos .

Ahora, por supuesto, puede crear estructuras que tengan campos que sean punteros a las funciones. Puede hacer que las estructuras tengan campos que sean punteros a matrices de punteros de función, correspondientes a tablas de métodos virtuales. Y así. Por supuesto, puede emular C ++ en C. Pero esa es una forma muy poco idiomática de programar en C; sería mejor usar C ++.

Y también, los archivos C son básicamente "módulos" separados, ¿verdad? ¿Entonces los módulos no son como "objetos"?

De nuevo, ¿qué características de los módulos piensas que los hacen actuar como objetos? ¿Los módulos admiten abstracción, encapsulación, mensajería, modularidad, polimorfismo y herencia?

La abstracción y la encapsulación son bastante débiles. Obviamente los módulos son modulares; Por eso se llaman módulos. ¿Mensajería? Solo en el sentido de que una llamada a método es un mensaje y los módulos pueden contener métodos. ¿Polimorfismo? No. ¿Herencia? No. Los módulos son candidatos bastante débiles para "objetos".

Eric Lippert
fuente
15
No estoy de acuerdo con que "emular C ++" (su término) no sea idiomático C. Un ejemplo contrario sería cómo un kernel de SO implementa típicamente operaciones de archivo: tome Linux como ejemplo, donde tiene estructuras llenas de punteros de función. Pueden ser modismos algo "específicos de dominio" (restringidos a escribir controladores en * nix, por ejemplo), pero son reconocibles y hacen el trabajo lo suficientemente limpio para algunos propósitos. También hay algunos ejemplos de bibliotecas de modo de usuario que hacen alguna noción de OO lo suficientemente bien; tome Gtk + y las bibliotecas de las que depende. Llámalo hacky y puede que tengas razón, pero no es terrible trabajar con ellos
asveikau
55
@asveikau: ¿La idea de que una práctica es inusual (incluso si no es desconocida) y "hacky" significa que, por definición, no es idiomática?
Adam Robinson
19
@asveikau: Claro, hay cosas que puedes hacer para que los programas C tengan más estilo OO. Pero como dices, se requiere disciplina para hacerlo; las características del lenguaje en sí mismas no lo conducen naturalmente a la encapsulación, el polimorfismo, la herencia de clases, etc. Por el contrario, el desarrollador puede imponer ese patrón en el lenguaje. Eso no significa que las estructuras sean lógicamente lo mismo que los objetos. Diablos, también puedes programar en un estilo OO en Lisp, pero eso no significa que las celdas de cons sean objetos.
Eric Lippert
3
@asveikau, ¿puedo sugerir que su (mala) interpretación de "idioma" como "propia" es moderadamente ... idiosincrásica? :)
Benjol
8
@BillK: Las estructuras no pueden contener código en C. Las estructuras pueden contener punteros de función , que son datos . Los punteros de función no son código . El código es un artefacto textual creado por un programador.
Eric Lippert
46

La palabra clave es "orientado", no "objeto". Incluso el código C ++ que usa objetos pero los usa como estructuras no está orientado a objetos .

C y C ++ pueden hacer OOP (aparte de no tener control de acceso en C), pero la sintaxis para hacerlo en C es inconveniente (por decir lo menos), mientras que la sintaxis en C ++ lo hace muy atractivo. C está orientado a procedimientos, mientras que C ++ está orientado a objetos, a pesar de capacidades centrales casi idénticas en ese sentido.

El código que usa objetos para implementar diseños que solo se pueden hacer con objetos (generalmente significa aprovechar el polimorfismo) es un código orientado a objetos. El código que usa objetos como poco más que bolsas de datos, incluso usando herencia en un lenguaje orientado a objetos, es realmente solo un código de procedimiento que es más complicado de lo que debe ser. El código en C que usa punteros de función que se cambian en tiempo de ejecución con estructuras llenas de datos está haciendo un poco de polimorfismo, y podría decirse que está "orientado a objetos", incluso en un lenguaje orientado a procedimientos.

kylben
fuente
2
+1 Para apuntar nuestra C puede ser OO. No es conveniente, pero se puede hacer.
dietbuddha
Es más fácil crear objetos en VBA, pero tampoco lo consideraría 'orientado' a objetos.
JeffO
VBA lo llamo "basado en objetos". Utiliza objetos, pero no polimórficamente, y en el poco trabajo que he hecho en él, no estoy seguro de que puedas hacer polimorfismo sin importar qué tipo de acrobacias de código intentes. Básicamente es un lenguaje de procedimiento con encapsulación.
kylben
2
La mayoría de los idiomas pueden actuar como un OO, funcional o prácticamente cualquier estilo de lenguaje. la diferencia es el "Orientado" y nunca antes lo había escuchado así. Desearía poder votar esto 3 veces y aceptarlo, es la respuesta correcta.
Bill K
1
@kylben No sería demasiado difícil almacenar el código SQL en la tabla y luego extraerlo y ejecutarlo (haciendo de la tabla su objeto) Sería un experimento interesante. En realidad es un poco tentador ...
Bill K
19

Basado en los directores de más alto nivel:

Un objeto es una encapsulación de datos y comportamiento de una manera interconectada, de modo que operan como un todo que se puede instanciar varias veces y trabajar como una caja negra si conoce la interfaz externa.

Las estructuras contienen datos pero no comportamientos y, por lo tanto, no pueden considerarse objetos.

Los módulos contienen tanto el comportamiento como los datos, pero no están encapsulados de tal manera que los dos estén relacionados y ciertamente no se puedan instanciar varias veces.

Y eso es antes de llegar a la herencia y el polimorfismo ...

Jon Hopkins
fuente
¿Cómo es que el comportamiento y los datos en los módulos no están relacionados? ¿No son las funciones miembro básicamente el 'comportamiento' en los datos que existen dentro del módulo?
Dark Templar
44
El problema es que no están encapsulados, no que no están relacionados.
Eoin Carroll
En realidad, los objetos se centran principalmente en el comportamiento , no en los datos. Los datos son / deberían ser ciudadanos de segunda clase en OOP. Las estructuras, en cambio, se centran en los datos y no tienen comportamiento.
Sklivvz
1
@Dark Templar - Lo que dijo Eoin ... Está en la naturaleza de la relación. Puedo ver de dónde vienes: ciertamente podrías usar Structs dentro de un módulo de tal manera que emule algunos elementos muy básicos de OO, pero gran parte de lo que harías dependería de que el programador se apegue a un conjunto de reglas autoimpuestas en lugar de que el lenguaje las imponga. ¿Y por qué te molestas? No está obteniendo ninguno de los beneficios de OO, por ejemplo, sin herencia, y se está restringiendo.
Jon Hopkins el
Esta es una mejor respuesta que la marcada como correcta.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
6

Las "estructuras" son solo datos. La prueba rápida y sucia habitual de "orientación a objetos" es: "¿Existe una estructura que permita encapsular el código y los datos como una sola unidad?". C falla eso, y por lo tanto es de procedimiento. C ++ pasa esa prueba.

Brian Knoblauch
fuente
66
Existen soluciones alternativas, las estructuras pueden tener punteros de función estática para funciones miembro. Necesitarán un thispuntero explícito , pero en ese caso, los datos y los medios para procesar los datos se encapsularán dentro de la estructura.
Codificador
@Brian Knoblauch: ¿pero no es un archivo C en sí mismo una encapsulación de datos y código?
Dark Templar
@DarkTemplar En cierto sentido, sí, pero a menos que logre crear unidades de traducción, compilarlas y cargarlas en el proceso de ejecución en tiempo de ejecución, esto no le sirve de nada.
unidades de traducción? >. <
Dark Templar
@Dark Templar: Una unidad de traducción es un archivo de origen más cualquier cosa #included en ella, y menos nada eliminado por no estar incluido condicionalmente ( #if, #ifdef, y similares).
David Thornley
5

C, al igual que C ++, tiene la capacidad de proporcionar abstracción de datos , que es un modismo del paradigma de programación orientado a objetos que existía antes.

  • Las estructuras C pueden tener datos (y ese es su propósito principal)
  • Las estructuras C también pueden definir punteros de función como datos
  • Las estructuras C pueden y a menudo tienen un conjunto de funciones asociadas con ellas, al igual que los métodos, solo que este puntero no se pasa implícitamente, pero debe especificarlo explícitamente como el primer argumento para cada método diseñado para manejar la estructura especificada. C ++ hace esto automáticamente por usted, tanto cuando define como llama a los métodos de clase / estructura.

OOP en C ++ extiende los medios para abstraer datos. Algunos dicen que es dañino , mientras que otros lo consideran una buena herramienta cuando se usa correctamente.

  • C ++ hace que este puntero sea implícito al no requerir que el usuario lo pase a "métodos de la clase / estructura" siempre que el tipo pueda ser (al menos en parte) identificado.
  • C ++ le permite restringir el acceso a ciertos métodos (funciones de clase) y, por lo tanto, permite más "programación defensiva" o "prueba de idiotas".
  • C ++ fomenta las abstracciones al proporcionar una mayor seguridad de tipo introduciendo
    1. El nuevo operador en lugar de malloc + cast
    2. Plantillas en lugar de punteros vacíos
    3. Funciones en línea que reciben valores escritos en lugar de macros
    4. Construido en polimorfismo que no tiene que implementar usted mismo, que le permite crear jerarquías de abstracción , contratos y especializaciones .

Sin embargo, encontrará que muchos "hackers" de C predican sobre cómo C es perfectamente capaz de obtener la cantidad justa de abstracción y cómo la sobrecarga creada por C ++ solo los distrae para resolver el problema real.

Modelos de programación abstractos ineficientes donde dos años más tarde notará que alguna abstracción no era muy eficiente, pero ahora todo su código depende de todos los modelos de objetos agradables que lo rodean, y no puede solucionarlo sin reescribir su aplicación. -- Linus Torvalds

Otros tienden a mirarlo de una manera más equilibrada, aceptando tanto las ventajas como las desventajas.

C facilita dispararse en el pie; C ++ lo hace más difícil, pero cuando lo hace, le vuela toda la pierna. -- Bjarne Stroustrup

Ñame Marcovic
fuente
2

Debes mirar el otro lado de la moneda: C ++.

En OOP, pensamos en un objeto abstracto (y diseñamos el programa en consecuencia), por ejemplo, un automóvil que puede detenerse, acelerar, girar a la izquierda o derecha, etc. Una estructura con un conjunto de funciones simplemente no se ajusta al concepto.

Con los objetos "reales" necesitamos ocultar los miembros, por ejemplo, o también podemos tener herencia con una relación "es" real y muchas más.

DESPUÉS DE LEER LOS COMENTARIOS A CONTINUACIÓN: Bueno, es cierto que (casi) todo se puede hacer con C (eso siempre es cierto), pero a primera vista pensé que lo que separa a c de c ++ es la forma en que piensas al diseñar un programa.

Lo único que realmente marca la diferencia es la imposición de políticas por parte del compilador . es decir, función virtual pura, y tal. pero esta respuesta solo se relacionará con problemas técnicos, pero creo que la diferencia principal (como se mencionó) es la forma original en que piensa mientras codifica, ya que C ++ le brinda una mejor sintaxis incorporada para hacer tales cosas, en lugar de hacer OOP en una manera algo torpe en C.

Guy L
fuente
No estoy seguro de por qué una estructura con un "conjunto de funciones" no se ajusta al concepto. +1 para la respuesta, sin embargo
Dark Templar
1
Aparte del control de acceso (privado / protegido / público) todo lo demás se puede hacer con estructuras.
Codificador
1
@DarkTemplar: Bueno, usted puede tratar de emular programación orientada a objetos en C (la gente ha escrito libros electrónicos en realidad en ese tema y hacerlo en el mundo real, aunque muy raramente), al igual que usted puede intentar emular la programación funcional en Java. Pero C proporciona ayuda cero, por lo tanto, C el lenguaje no está orientado a objetos .
1

Lo dijiste tú mismo. Si bien C tiene cosas que son como objetos similares, todavía no son objetos, y es por eso que C no se considera un lenguaje OOP.

ryanzec
fuente
1
Bueno, supongo que la pregunta es: ¿por qué y dónde se dibuja la línea para qué es un objeto y qué no?
Dark Templar
1

Orientado a objetos se refiere tanto a un patrón arquitectónico (o incluso a un metapatrón) como a los lenguajes que tienen características para ayudar a implementar o exigir el uso de este patrón.

Puede implementar un diseño "OO" (el escritorio Gnome es quizás el mejor ejemplo de OO hecho en C puro), ¡incluso he visto esto hecho con COBOL!

Sin embargo, poder implementar una dosis de diseño OO no hace que el lenguaje sea OO. Los puristas argumentarían que Java y C ++ no son realmente OO, ya que no puede anular o heredar los "tipos" básicos como "int" y "char", y Java no admite la herencia múltiple. Pero como son los lenguajes OO más utilizados y son compatibles con la mayoría de los paradigmas, la mayoría de los programadores "reales" a los que se les paga para producir código de trabajo los consideran los lenguajes OO.

C, por otro lado, solo admite estructuras (como lo hacen COBOL, Pascal y docenas de otros lenguajes de procedimiento), podría argumentar que admite la herencia múltiple, ya que puede usar cualquier función en cualquier dato, pero la mayoría consideraría esto como un error. que una característica

James Anderson
fuente
0

Veamos la definición de OO:

  • Mensajería
  • Encapsulamiento
  • Enlace tardío

C no proporciona ninguno de esos tres. En particular, no proporciona mensajería , que es la más importante.

Jörg W Mittag
fuente
1
Creo que tendría que estar en desacuerdo con eso. Seguramente puede tener mensajes en C, trabaje con las API de Objective C desde C y lo descubrirá en profundidad, y el enlace tardío se puede hacer a través de punteros de función, pero no obtiene mucho azúcar sintáctico para ocultarlo. (La encapsulación es realmente fácil en C; los punteros a tipos de estructura incompletos hacen el trabajo a la perfección.)
Donal Fellows
La herencia también se considera importante en OO, y C no hace eso. Lo más parecido a la encapsulación en C son archivos separados que pueden tener staticfunciones internas ( ) y miembros de datos.
David Thornley
@DonalFellows, el mensaje real que pasa en Objective-C podría implementarse fácilmente como una macro C99. Lo único que tiene el compilador es que genera estáticamente todas las estructuras necesarias a partir de unas pocas líneas de código de alto nivel. La mayoría, si no todas, las funciones están disponibles en la API de C.
qpr
0

Hay una serie de ingredientes clave para OO, pero los más importantes son que la mayoría del código no sabe qué hay dentro de un objeto (ven la interfaz de la superficie, no la implementación), que el estado de un objeto es una unidad administrada (es decir, cuando el objeto deja de ser, también lo hace su estado), y cuando algún código invoca una operación en un objeto, lo hacen sin saber exactamente qué es o implica esa operación (todo lo que hacen es seguir un patrón para lanzar un "Mensaje" sobre la pared).

C encapsula muy bien; el código que no ve la definición de una estructura no puede (legítimamente) mirar dentro de ella. Todo lo que necesita hacer es poner una definición como esta en un archivo de encabezado:

struct FooImpl;
typedef struct FooImpl *Foo;

Por supuesto, habrá una necesidad de una función que construya Foos (es decir, una fábrica) y que delegue parte del trabajo al propio objeto asignado (es decir, a través de un método de "constructor"), y que también tenga una manera de deshacerse del objeto nuevamente (mientras lo deja limpiar a través de su método de "destructor") pero eso es detalles.

El envío de métodos (es decir, mensajes) también se puede hacer a través de la convención de que el primer elemento de la estructura es en realidad un puntero a una estructura llena de punteros de función, y que cada uno de esos punteros de función debe tomar un Foocomo su primer argumento. Dispatch se convierte en una cuestión de buscar la función y llamarla con el argumento correcto reescribir, lo que no es tan difícil de hacer con una macro y un poco de astucia. (Esa tabla de funciones es el núcleo de lo que realmente es una clase en un lenguaje como C ++).

Además, eso también le proporciona un enlace tardío: todo lo que sabe el código de envío es que está invocando un desplazamiento particular en una tabla señalada por el objeto. Eso solo debe establecerse durante la asignación e inicialización del objeto. Es posible utilizar esquemas de despacho aún más complejos que le brindan más dinamismo de tiempo de ejecución (a un costo de velocidad), pero son cerezas además del mecanismo básico.

Sin embargo, eso no significa que C sea un lenguaje OO. La clave es que C te deja hacer todo el trabajo complicado de escribir las convenciones y el mecanismo de envío tú mismo (o usar una biblioteca de terceros). Eso es mucho trabajo. Tampoco proporciona soporte sintáctico o semántico, por lo que implementar un sistema de clase completo (con cosas como la herencia) sería innecesariamente doloroso; Si se trata de un problema complejo que está bien descrito por un modelo OO, un lenguaje OO será muy útil para escribir la solución. La complejidad adicional puede justificarse.

Compañeros de Donal
fuente
0

Creo que C está perfectamente bien y decente para implementar conceptos orientados a objetos, encogerse de hombros . La mayoría de las diferencias, según lo veo, entre el subconjunto común de denominadores de lenguajes considerados orientados a objetos son menores y de naturaleza sintáctica desde mi punto de vista pragmático.

Comencemos con, digamos, ocultar información. En C podemos lograr eso simplemente ocultando la definición de una estructura y trabajando con ella a través de punteros opacos. Eso modela efectivamente la distinción publicvs. privatelos campos de datos a medida que lo hacemos con las clases. Y es bastante fácil de hacer y apenas anti-idiomático, ya que la biblioteca C estándar se basa en gran medida en esto para lograr ocultar la información.

Por supuesto, pierde la capacidad de controlar fácilmente exactamente dónde se asigna la estructura en la memoria mediante el uso de tipos opacos, pero eso es solo una diferencia notable entre, por ejemplo, C y C ++. C ++ es definitivamente una herramienta superior cuando se compara su capacidad para programar conceptos orientados a objetos sobre C mientras se mantiene el control sobre los diseños de memoria, pero eso no significa necesariamente que Java o C # sean superiores a C en ese sentido, ya que esos dos te hacen pierde por completo la capacidad de controlar dónde se asignan los objetos en la memoria.

Y tenemos que usar una sintaxis como fopen(file, ...); fclose(file);en lugar de un file.open(...); file.close();gran whoop. ¿A quien le importa? Tal vez solo alguien que se apoya mucho en la autocompletación en su IDE. Admito que puede ser una característica muy útil desde un punto de vista práctico, pero tal vez no una que requiera una discusión sobre si un lenguaje es adecuado para la POO.

Carecemos de la capacidad de implementar efectivamente los protectedcampos. Me someteré totalmente allí. Pero no creo que haya una regla concreta que diga: " Todos los lenguajes OO deberían tener una función que permita a las subclases acceder a miembros de una clase base a la que los clientes normales aún no deberían tener acceso ". Además, rara vez veo casos de uso para miembros protegidos que no son al menos un poco sospechosos de convertirse en un obstáculo de mantenimiento.

Y, por supuesto, tenemos que "emular" el polimorfismo OO con tablas de punteros de función y punteros para enviarlos dinámicamente con un poco más de repetitivo para inicializar aquellos analógicos vtablesy vptrs, pero un poco de repetitivo nunca me causó mucho dolor.

La herencia es muy parecida. Podemos modelarlo fácilmente a través de la composición, y en el funcionamiento interno de los compiladores se reduce a lo mismo. Por supuesto, perdemos la seguridad de los tipos si queremos hacer downcast , y diría que si quieres hacer downcasts , no uses C para eso porque las cosas que las personas hacen en C para emular el downcast pueden ser horribles por un tipo punto de vista de seguridad, pero prefiero que la gente no se desanime en absoluto. La seguridad de tipos es algo que puede comenzar a pasar por alto fácilmente en C, ya que el compilador proporciona tanta libertad para interpretar cosas como solo bits y bytes, sacrificando la capacidad de detectar posibles errores en tiempo de compilación, pero algunos lenguajes considerados no están orientados a objetos ni siquiera estáticamente escrito.

No sé, creo que está bien. Por supuesto, no usaría C para intentar crear una base de código a gran escala que se ajuste a los principios SÓLIDOS, pero no necesariamente se debe a sus defectos en el frente orientado a objetos. Muchas de las características que extrañaría si intentara usar C para tal fin estarían relacionadas con las características del lenguaje que no se consideran directamente un requisito previo para la POO, como la seguridad de tipo fuerte, destructores que se invocan automáticamente cuando los objetos están fuera de alcance, operador sobrecarga, plantillas / genéricos y manejo de excepciones. Es cuando me faltan esas características auxiliares que alcanzo para C ++.


fuente
1
No estoy seguro de cómo los constructores no podrían considerarse un requisito previo para OOP. Parte de la esencia básica de la encapsulación es la capacidad de garantizar invariantes para un objeto. Y eso requiere poder inicializar adecuadamente el objeto dentro de esos invariantes. Eso requiere un constructor: una o más funciones, de modo que no se pueda decir que el objeto existe hasta que se haya llamado al menos a una de ellas.
Nicol Bolas
Cuando tenemos información oculta con tipos opacos, la única forma de instanciarlos y copiarlos / clonarlos y destruirlos es a través del equivalente analógico de funciones que sirven como constructores y destructores con la misma capacidad de mantener esos invariantes. Es que no es modelada directamente en la lengua y podría parecerse a la forma de foo_createy foo_destroy, y foo_clone, por ejemplo
Todo lo que necesitamos para mantener invariantes struct Fooen tal caso es asegurarnos de que sus miembros de datos no puedan ser accedidos y mutados por el mundo exterior, que los tipos opacos (declarados pero no definidos para el mundo exterior) dan de inmediato. Podría decirse que es una forma más fuerte de ocultar información, a la par de la de un pimplen C ++.
Sí, sé cómo las personas implementan OOP en C, gracias. Mi punto fue que su declaración de que los constructores "no se consideran directamente un requisito previo para OOP" es un error.
Nicol Bolas
Ya veo, déjame corregir eso ... pero en ese caso, ¿podríamos decir que C proporciona soporte (¿adecuado?) Para destructores y constructores?
-1

No es una mala pregunta

Si va a llamar a c un lenguaje OO, necesitaría llamar a casi todos los lenguajes de procedimiento OO también. Entonces haría que el término no tuviera sentido. c no tiene soporte de idioma para OO. Si tiene estructuras, pero las estructuras typesno son clases.

En realidad, c no tiene muchas características en comparación con la mayoría de los lenguajes. Se utiliza principalmente por su velocidad, simplicidad, popularidad y soporte, incluidas toneladas de bibliotecas.

Glen P
fuente