Por que C não é considerado uma linguagem 'orientada a objetos'?

92

Parece que C tem seus próprios quase-objetos, como "estruturas" que podem ser considerados objetos (da maneira de alto nível que normalmente pensamos).

E também, os arquivos C são basicamente "módulos" separados, certo? Então os módulos também não são como 'objetos'? Estou confuso sobre o motivo pelo qual C, que parece tão semelhante ao C ++, é considerado uma linguagem "procedural" de baixo nível, onde C ++ é um "orientado a objetos" de alto nível.

* edit: (esclarecimento) por que e onde, a linha é desenhada, pois o que é um 'objeto' e não é?

Templário Sombrio
fonte
40
Todos - por que os votos negativos? É uma pergunta básica, mas não ruim.
91111 Jon Hopkins
7
Você pode usar os princípios de OO efetivamente em C (e as pessoas que escrevem código C normalmente), mas o idioma não é criado para facilitar, como muitas linguagens mais recentes.
As11:
5
C simplesmente possui uma abordagem diferente, mais simples e (para ser honesta) melhor definida (pelo menos entre a comunidade de código aberto) para abstração de dados. O C ++ tende a ser uma potência de abstração e permite muitas coisas excelentes, mas vem com o custo de ter que entender como [não] usá-las adequadamente, o que é mais frequente nos programas comuns. Veja minha resposta completa para mais detalhes.
Yam Marcovic 10/10
1
Em breve: estruturas não podem ter métodos. (O ponteiro para uma função não é suficiente).
SF.
1
É possível fazer programação baseada em objetos em C, com alguma dificuldade. Mas isso não o torna orientado a objetos .
Wedge

Respostas:

101

Parece que C tem seus próprios quase-objetos, como 'estruturas' que podem ser considerados objetos

Vamos juntos, você e eu, ler a página da Wikipedia sobre programação orientada a objetos e verificar os recursos das estruturas no estilo C que correspondem ao que é tradicionalmente considerado estilo orientado a objetos:

(OOP) é ​​um paradigma de programação usando "objetos" - estruturas de dados que consistem em campos e métodos de dados, juntamente com suas interações

As estruturas C consistem em campos e métodos, juntamente com suas interações ? Não.

As técnicas de programação podem incluir recursos como abstração de dados, encapsulamento, sistema de mensagens, modularidade, polimorfismo e herança.

As estruturas C fazem alguma dessas coisas de maneira "de primeira classe"? Não. A linguagem funciona contra você a cada passo do caminho.

a abordagem orientada a objetos incentiva o programador a colocar dados onde não são diretamente acessíveis pelo restante do programa

As estruturas C fazem isso? Não.

Um programa orientado a objetos geralmente contém diferentes tipos de objetos, cada tipo correspondendo a um tipo específico de dados complexos a serem gerenciados ou talvez a um objeto ou conceito do mundo real

As estruturas C fazem isso? Sim.

Os objetos podem ser considerados como agrupando seus dados em um conjunto de funções projetadas para garantir que os dados sejam usados ​​adequadamente

Não.

cada objeto é capaz de receber mensagens, processar dados e enviar mensagens para outros objetos

Uma estrutura pode enviar e receber mensagens? Não. Ele pode processar dados? Não.

As estruturas de dados OOP tendem a "transportar seus próprios operadores com eles"

Isso acontece em C? Não.

Expedição dinâmica ... Encapsulamento ... Polimorfismo de subtipo ... Herança de objetos ... Recursão aberta ... Classes de objetos ... Instâncias de classes ... Métodos que atuam nos objetos anexados ... Passagem de mensagens .. Abstração

Há algum desses recursos das estruturas C? Não.

Precisamente, quais características das estruturas você acha que são "orientadas a objetos"? Porque eu não posso encontrar qualquer que não seja o fato de que estruturas definem tipos .

Agora, é claro que você pode criar estruturas que possuem campos que são indicadores de funções. Você pode fazer com que as estruturas tenham campos que são ponteiros para matrizes de ponteiros de função, correspondentes a tabelas de métodos virtuais. E assim por diante. É claro que você pode emular C ++ em C. Mas essa é uma maneira muito não-idiomática de programar em C; seria melhor você usar C ++.

E também, os arquivos C são basicamente "módulos" separados, certo? Então os módulos também não são como 'objetos'?

Novamente, em quais características dos módulos você pensa que os fazem agir como objetos? Os módulos suportam abstração, encapsulamento, sistema de mensagens, modularidade, polimorfismo e herança?

Abstração e encapsulamento são bem fracos. Obviamente, os módulos são modulares; é por isso que eles são chamados de módulos. Mensagens? Somente no sentido de que uma chamada de método é uma mensagem e os módulos podem conter métodos. Polimorfismo? Não. Herança? Não. Módulos são candidatos bastante fracos para "objetos".

Eric Lippert
fonte
15
Eu discordo que "emular C ++" (seu termo) não é idiomático C. Um exemplo contrário seria como um kernel do SO normalmente implementa operações de arquivo - tome o Linux como exemplo, onde você tem estruturas cheias de indicadores de função. Eles podem ser expressões "específicas do domínio" (restritas à gravação de drivers no * nix, por exemplo), mas são reconhecíveis e fazem o trabalho de maneira suficientemente limpa para alguns propósitos. Existem também alguns exemplos de bibliotecas de modo de usuário que fazem alguma noção de OO suficientemente bem; pegue o Gtk + e as bibliotecas das quais depende. Chamá-lo de hacky e você pode estar certo, mas estes não são terríveis para trabalhar com
asveikau
5
@asveikau: A idéia de que uma prática é incomum (mesmo que não seja desconhecida) e "hacky" significa que, por definição, não é idiomática?
Adam Robinson
19
@asveikau: Claro, há coisas que você pode fazer para tornar os programas C mais elegantes em OO. Mas, como você diz, requer disciplina para fazê-lo; as características da linguagem em si não o levam naturalmente ao encapsulamento, polimorfismo, herança de classe e assim por diante. Em vez disso, o desenvolvedor pode impor esse padrão na linguagem. Isso não significa que as estruturas são logicamente a mesma coisa que os objetos. Caramba, você também pode programar no estilo OO no Lisp, mas isso não significa que as células contras sejam objetos.
Eric Lippert
3
@asveikau, posso sugerir que a sua (mis) interpretação de "idioma" como "próprio" é levemente ... idiossincrática? :)
Benjol 11/11
8
@ BillK: Structs não podem conter código em C. Structs podem conter ponteiros de função , que são dados . Ponteiros de função não são código . Código é um artefato textual criado por um programador.
Eric Lippert
46

A palavra-chave é "orientada", não "objeto". Mesmo o código C ++ que usa objetos, mas os usa como estruturas, não é orientado a objetos .

C e C ++ podem fazer OOP (além de nenhum controle de acesso em C), mas a sintaxe para fazê-lo em C é inconveniente (para dizer o mínimo), enquanto a sintaxe em C ++ o torna muito convidativo. C é orientado a procedimentos, enquanto C ++ é orientado a objetos, apesar dos recursos principais quase idênticos a esse respeito.

O código que usa objetos para implementar projetos que só podem ser feitos com objetos (geralmente significa tirar vantagem do polimorfismo) é um código orientado a objetos. O código que usa objetos com pouco mais do que pacotes de dados, mesmo usando herança em uma linguagem orientada a objetos, é realmente apenas um código processual que é mais complicado do que precisa ser. Código em C que usa ponteiros de função que são alterados em tempo de execução com estruturas cheias de dados está meio que polimorfismo, e pode-se dizer que é "orientado a objetos", mesmo em uma linguagem orientada a procedimentos.

kylben
fonte
2
+1 Para apontar, nosso C pode ser OO. Não é conveniente, mas pode ser feito.
dietbuddha
É mais fácil criar objetos no VBA, mas eu também não consideraria o objeto 'orientado'.
JeffO 11/10
VBA eu chamo de "objeto baseado". Ele usa objetos, mas não polimorficamente, e no pouco trabalho que fiz nele, não tenho certeza de que você possa fazer polimorfismo, independentemente do tipo de acrobacia de código que você tentar. É basicamente uma linguagem processual com encapsulamento.
Kllben
2
A maioria dos idiomas pode atuar como OO, funcional ou praticamente qualquer estilo de linguagem. a diferença é o "orientado" e eu nunca tinha ouvido isso dessa maneira antes. Eu gostaria de poder votar 3 vezes e aceitá-lo, é a resposta certa.
Bill K
1
@kylben Não seria exagero armazenar o código SQL na tabela e depois extraí-lo e executá-lo (tornando a tabela seu objeto) Seria uma experiência interessante. Na verdade, é um pouco tentador ...
Bill K
19

Com base nos principais de nível mais alto:

Um objeto é um encapsulamento de dados e comportamento de maneira interligada, de modo que eles operem como um todo, que podem ser instanciados várias vezes e trabalhados como uma caixa preta, se você conhece a interface externa.

As estruturas contêm dados, mas nenhum comportamento e, portanto, não podem ser considerados objetos.

Os módulos contêm comportamento e dados, mas não são encapsulados de forma que os dois estejam relacionados e certamente não podem ser instanciados várias vezes.

E isso é antes de você entrar em herança e polimorfismo ...

Jon Hopkins
fonte
Como é que o comportamento e os dados nos módulos não estão relacionados? As funções de membro não são basicamente o 'comportamento' dos dados que existem dentro do módulo?
Escuro Templar
4
O problema é que eles não estão encapsulados, não estão relacionados.
Eoin Carroll
Na verdade, os objetos são centralizados principalmente no comportamento , não nos dados. Os dados são / devem ser cidadãos de segunda classe no POO. As estruturas, em vez disso, são centradas nos dados e não têm comportamento.
Sklivvz
1
@ Dark Templar - O que Eoin disse ... É da natureza do relacionamento. Eu posso ver de onde você é - você certamente poderia usar o Structs dentro de um módulo de tal maneira que emulasse alguns elementos muito muito básicos do OO, mas muito do que você estaria fazendo dependeria do programador aderir a um conjunto de regras auto-impostas, em vez de o idioma impor. E por que você se incomodaria? Você não obtém nenhum dos benefícios do OO - nenhuma herança, por exemplo - e está se restringindo.
91111 Jon Hopkins
Esta é uma resposta melhor do que a marcada como correta.
Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
6

"structs" são apenas dados. O teste rápido e sujo usual de "orientação a objetos" é: "Existe uma estrutura que permite que códigos e dados sejam encapsulados como uma única unidade?". C falha nisso e, portanto, é processual. C ++ passa nesse teste.

Brian Knoblauch
fonte
6
Existem soluções alternativas, as estruturas podem ter ponteiros de função estática para funções de membro. Eles precisarão de um thisponteiro explícito , mas, nesse caso, os dados e os meios para processar os dados serão encapsulados dentro da estrutura.
Coder
@ Brian Knoblauch: mas não é um arquivo C em si um encapsulamento de dados e código?
Escuro Templar
@DarkTemplar De certa forma, sim, mas a menos que você consiga criar unidades de tradução, compile-as e carregue-as no processo em execução no tempo de execução, isso é pouco.
unidades de tradução? >. <
Templário das Trevas 10/10
@Dark Templar: A unidade de tradução é um arquivo de origem mais qualquer coisa #includede d para ele, e menos qualquer coisa removido por não ser condicionalmente incluído ( #if, #ifdefe afins).
David Thornley 11/11
5

C, assim como o C ++, tem a capacidade de fornecer Abstração de Dados , que é um idioma do paradigma de programação orientada a objetos que existia antes dele.

  • Estruturas C podem ter dados (e esse é o seu principal objetivo)
  • Estruturas C também podem definir ponteiros de função como dados
  • As estruturas C podem e frequentemente têm um conjunto de funções associadas a elas, assim como os métodos, apenas o ponteiro this não é passado implicitamente, mas você deve especificá-lo explicitamente como o primeiro argumento para cada método projetado para manipular a estrutura especificada. O C ++ faz isso automaticamente para você, quando você define e chama métodos de classe / estrutura.

OOP em C ++ estende os meios para abstrair dados. Alguns dizem que é prejudicial , enquanto outros consideram uma boa ferramenta quando usada corretamente.

  • O C ++ torna implícito o ponteiro this , não exigindo que o usuário o passe para "métodos da classe / estrutura", desde que o tipo possa ser (pelo menos em parte) identificado.
  • O C ++ permite restringir o acesso a determinados métodos (funções de classe) e, portanto, permite mais "programação defensiva" ou "à prova de idiotas".
  • O C ++ incentiva abstrações, fornecendo segurança de tipo mais forte, introduzindo
    1. O novo operador em vez de malloc + cast
    2. Modelos em vez de ponteiros nulos
    3. Funções embutidas recebendo valores digitados em vez de macros
    4. Polimorfismo embutido que você não precisa implementar sozinho, que permite criar hierarquias de abstração , contratos e especializações .

No entanto, você encontrará muitos "hackers" C pregando como o C é perfeitamente capaz da quantidade certa de abstração e como a sobrecarga criada pelo C ++ apenas os distrai da solução do problema real.

Modelos de programação abstratos ineficientes em que, dois anos depois, você percebe que alguma abstração não era muito eficiente, mas agora todo o seu código depende de todos os bons modelos de objetos ao seu redor e não é possível corrigi-lo sem reescrever seu aplicativo. -- Linus Torvalds

Outros tendem a vê-lo de uma maneira mais equilibrada, aceitando as vantagens e as desvantagens.

C facilita o tiro no pé; O C ++ torna mais difícil, mas quando você o faz explodir toda a sua perna. - Bjarne Stroustrup

Yam Marcovic
fonte
2

Você precisa olhar para o outro lado da moeda: C ++.

Em OOP, pensamos em um objeto abstrato (e projetamos o programa de acordo), por exemplo, um carro que pode parar, acelerar, virar à esquerda ou à direita, etc. Uma estrutura com um conjunto de funções simplesmente não se encaixa no conceito.

Com objetos "reais", precisamos ocultar os membros, por exemplo, ou também podemos ter herança com um relacionamento real "é um" e muito mais.

APÓS LER OS COMENTÁRIOS ABAIXO: Bem, é certo que (quase) tudo pode ser feito com C (isso sempre é verdade), mas, à primeira vista, pensei que o que separa c de c ++ é a maneira que você pensa ao criar um programa.

A única coisa que realmente faz a diferença é a imposição de políticas pelo compilador . ou seja, função virtual pura, e tal. mas essa resposta só se relaciona a problemas técnicos, mas acho que a principal diferença (como mencionada) é a maneira original como você pensa enquanto codifica, pois o C ++ oferece uma sintaxe melhor incorporada para fazer essas coisas, em vez de fazer OOP em uma maneira um pouco desajeitada em C.

Guy L
fonte
Não sabe ao certo por que uma estrutura com um "pacote de funções" não se encaixa no conceito? No entanto, +1 para a resposta
Dark Templar
1
Além do controle de acesso (privado / protegido / público), tudo o mais pode ser feito com estruturas.
Coder
1
@DarkTemplar: Bem, você pode tentar emular OOP em C (as pessoas realmente escreveram ebooks sobre esse tópico e fazê-lo no mundo real, embora muito raramente), como você pode tentar emular a programação funcional em Java. Mas C não fornece ajuda para isso; portanto, C a linguagem não é orientada a objetos .
1

Você meio que disse isso sozinho. Enquanto C tem coisas que são como objetos semelhantes, eles ainda não são objetos, e é por isso que C não é considerado uma linguagem OOP.

ryanzec
fonte
1
Bem, acho que a pergunta é: por que e onde é traçada a linha do que é um objeto e o que não é?
Escuro Templar
1

Orientado a objeto refere-se a um padrão arquitetural (ou mesmo a um meta-padrão) e às linguagens que possuem recursos para ajudar a implementar ou exigir o uso desse padrão.

Você pode implementar um design "OO" (a área de trabalho do Gnome é talvez o melhor exemplo de OO feito em C puro). Eu já vi isso com o COBOL!

No entanto, ser capaz de implementar uma dose de projeto OO não torna a linguagem OO. Os puristas argumentam que Java e C ++ não são verdadeiramente OO, pois você não pode substituir ou herdar os "tipos" básicos, como "int" e "char", e Java não suporta herança múltipla. Porém, como são as linguagens OO mais usadas e suportam a maioria dos paradigmas, os programadores "reais" que são pagos para produzir código de trabalho os consideram as linguagens OO.

C, por outro lado, suporta apenas estruturas (como COBOL, Pascal e dezenas de outras linguagens processuais), você poderia argumentar que suporta herança múltipla, pois você pode usar qualquer função em qualquer parte dos dados, mas a maioria consideraria isso um erro. do que um recurso.

James Anderson
fonte
0

Vamos apenas olhar para a definição de OO:

  • Mensagens
  • Encapsulamento
  • Ligação tardia

C não fornece nenhum desses três. Em particular, ele não fornece o Messaging , que é o mais importante.

Jörg W Mittag
fonte
1
Eu acho que teria que discordar disso. Você certamente pode ter mensagens em C - trabalhe com APIs de Objective C de C e descobre isso em profundidade - e a ligação tardia pode ser feita por meio de ponteiros de função, mas você não recebe muito açúcar sintático para ocultá-la. (Encapsulamento é realmente fácil em C; ponteiros para tipos de estrutura incompletos fazer o trabalho perfeitamente.)
Donal Fellows
A herança também é considerada importante no OO, e C não faz isso. O mais próximo do encapsulamento em C são arquivos separados que podem ter staticfunções internas ( ) e membros de dados.
David Thornley 11/11
@DonalFellows, a mensagem real que passa no Objective-C pode ser facilmente implementada como uma macro C99. A única coisa que o compilador tem a oferecer é que ele gera todas as estruturas necessárias estaticamente a partir de algumas linhas de código de alto nível. A maioria, se não todos, os recursos estão disponíveis na API C.
Qr 11/11
0

Existem vários ingredientes principais para o OO, mas os principais são que a maioria do código não sabe o que está dentro de um objeto (eles veem a interface da superfície, não a implementação), que o estado de um objeto é uma unidade gerenciada (ou seja, quando o objeto deixa de existir, o mesmo ocorre com o seu estado) e, quando algum código invoca uma operação em um objeto, eles o fazem sem saber exatamente o que essa operação é ou envolve (tudo o que fazem é seguir um padrão para lançar um “Mensagem” por cima do muro).

C encapsula muito bem; código que não vê a definição de uma estrutura não pode (legitimamente) espiar dentro dela. Tudo o que você precisa fazer é colocar uma definição como essa em um arquivo de cabeçalho:

struct FooImpl;
typedef struct FooImpl *Foo;

Obviamente, haverá uma necessidade de uma função que construa Foos (ou seja, uma fábrica) e que deva delegar parte do trabalho ao próprio objeto alocado (ou seja, através de um método "construtor"), e também de ter uma maneira de descartar o objeto novamente (ao mesmo tempo em que limpa através do método "destruidor"), mas isso é detalhes.

O envio de métodos (isto é, mensagens) também pode ser feito através da convenção de que o primeiro elemento da estrutura é realmente um ponteiro para uma estrutura cheia de ponteiros de função e que cada um desses ponteiros de função deve ter Foocomo primeiro argumento. A expedição passa a ser uma questão de procurar a função e chamá-la com o argumento correto reescrito, o que não é tão difícil de fazer com uma macro e um pouco de astúcia. (Essa tabela de funções é o núcleo do que realmente é uma classe em uma linguagem como C ++.)

Além disso, isso também fornece uma ligação tardia: tudo o que o código de despacho sabe é que está invocando um deslocamento específico em uma tabela apontada pelo objeto. Isso só precisa ser definido durante a alocação e inicialização do objeto. É possível usar esquemas de despacho ainda mais complexos que compram mais dinamismo de tempo de execução (a um custo de velocidade), mas são cerejas no topo do mecanismo básico.

No entanto, isso não significa que C seja uma linguagem OO. A chave é que C deixa você fazer todo o trabalho complicado de escrever as convenções e o mecanismo de envio (ou usar uma biblioteca de terceiros). Isso dá muito trabalho. Também não fornece suporte sintático ou semântico, portanto, implementar um sistema de classe completo (com coisas como herança) seria desnecessariamente doloroso; se você estiver lidando com um problema complexo que é bem descrito por um modelo OO, uma linguagem OO será muito útil para escrever a solução. A complexidade extra pode ser justificada.

Donal Fellows
fonte
0

Eu acho que C é perfeitamente bom e decente para implementar conceitos orientados a objetos, encolher os ombros . A maioria das diferenças que eu vejo entre o subconjunto denominador comum de linguagens consideradas orientadas a objetos são de natureza menor e sintática do meu tipo de ponto de vista pragmático.

Vamos começar com, digamos, ocultação de informações. Em C, podemos conseguir isso simplesmente ocultando a definição de uma estrutura e trabalhando com ela através de ponteiros opacos. Isso efetivamente modela a distinção publicvs. privatecampos de dados à medida que obtemos as classes. E é fácil o suficiente e dificilmente anti-idiomático, pois a biblioteca C padrão depende muito disso para obter informações ocultas.

É claro que você perde a capacidade de controlar facilmente exatamente onde a estrutura é alocada na memória usando tipos opacos, mas essa é apenas uma diferença notável entre, digamos, C e C ++. Definitivamente, o C ++ é uma ferramenta superior ao comparar sua capacidade de programar conceitos orientados a objetos sobre C, mantendo o controle sobre layouts de memória, mas isso não significa necessariamente que Java ou C # seja superior a C nesse sentido, pois esses dois fazem você perder completamente a capacidade de controlar onde os objetos estão alocados na memória.

E nós temos que usar uma sintaxe como fopen(file, ...); fclose(file);em oposição a file.open(...); file.close();mas grande grito. Quem realmente se importa? Talvez apenas alguém que se apóia fortemente na conclusão automática em seu IDE. Admito que possa ser um recurso muito útil do ponto de vista prático, mas talvez não seja necessário um debate sobre se um idioma é adequado para o POO.

Não temos a capacidade de implementar efetivamente os protectedcampos. Eu vou me submeter totalmente lá. Mas não acho que exista uma regra concreta que diga: " Todos os idiomas OO devem ter um recurso para permitir que as subclasses acessem membros de uma classe base que ainda não devem ser acessados ​​por clientes normais ". Além disso, raramente vejo casos de uso para membros protegidos que não suspeitam de se tornar um obstáculo de manutenção.

E é claro que precisamos "emular" o polimorfismo OO com tabelas de ponteiros de função e ponteiros para eles para envio dinâmico com um pouco mais de clichê para inicializar aqueles analógicos vtablese vptrs, mas um pouco de clichê nunca me causou muita dor.

A herança é da mesma maneira. Podemos modelar isso facilmente através da composição e, no funcionamento interno dos compiladores, tudo se resume à mesma coisa. É claro que perdemos a segurança do tipo se queremos fazer downcast , e aí eu diria que se você quiser fazer downcast , não use C para isso, porque as coisas que as pessoas fazem em C para emular o downcast podem ser horríveis para um tipo ponto de vista da segurança, mas prefiro que as pessoas não fiquem abatidas . Segurança de tipo é algo que você pode facilmente perder em C, pois o compilador oferece muita margem de manobra para interpretar coisas como apenas bits e bytes, sacrificando a capacidade de detectar possíveis erros no tempo de compilação, mas algumas linguagens consideradas não orientadas a objetos mesmo digitado estaticamente.

Então não sei, acho que está bem. É claro que eu não usaria C para tentar criar uma base de código em larga escala que esteja em conformidade com os princípios do SOLID, mas isso não é necessariamente devido a suas falhas na frente orientada a objetos. Muitos dos recursos que eu perderia se tentasse usar C para esse objetivo estariam relacionados a recursos de linguagem não considerados diretamente um pré-requisito para OOP, como segurança de tipo forte, destruidores que são automaticamente invocados quando objetos ficam fora do escopo, operador sobrecarga, modelos / genéricos e tratamento de exceções. É quando sinto falta dos recursos auxiliares que alcanço em C ++.


fonte
1
Não tenho certeza de como os construtores não podem ser considerados um pré-requisito para OOP. Parte da essência básica do encapsulamento é a capacidade de garantir invariantes para um objeto. E isso requer ser capaz de inicializar adequadamente o objeto dentro desses invariantes. Isso requer um construtor: uma ou mais funções, de modo que você não possa dizer que o objeto ainda existe até que pelo menos uma delas tenha sido chamada.
Nicol Bolas
Quando temos informações ocultas com tipos opacos, a única maneira de instanciar e copiar / clonar e destruí-las é através do equivalente analógico de funções que servem como construtores e destruidores com a mesma capacidade de manter esses invariantes. É só não diretamente modelado para a língua e pode assemelhar-se a forma de foo_createe foo_destroye foo_clone, por exemplo
Tudo o que precisamos para manter os invariantes struct Foonesse caso é garantir que seus membros de dados não possam ser acessados ​​e mutados pelo mundo externo, que tipos opacos (declarados mas não definidos para o mundo externo) fornecem imediatamente. É sem dúvida uma forma mais forte de ocultar informações, a par com a de um pimplem C ++.
Sim, eu sei como as pessoas implementam OOP em C, obrigado. Meu argumento foi que sua afirmação de que os construtores "não são considerados diretamente um pré-requisito para OOP" está errada.
Nicol Bolas
Entendo, deixe-me corrigir isso ... mas, nesse caso, podemos dizer que C fornece suporte (adequado?) Para destruidores e construtores?
-1

Não é uma pergunta ruim.

Se você quiser chamar c de uma linguagem OO, também precisará chamar todas as linguagens procedurais de OO. Então isso tornaria o termo sem sentido. c não tem suporte a idiomas para OO. Se possui estruturas, mas estruturas typesnão são classes.

Na verdade, c não possui muitos recursos em comparação com a maioria dos idiomas. É usado principalmente por sua velocidade, simplicidade, popularidade e suporte, incluindo toneladas de bibliotecas.

Glen P
fonte