C ++ não é adequado para OOP? [fechadas]

12

Eu li em algum lugar em uma das respostas a uma pergunta aqui (não me lembro qual) que C ++ não é adequado para programação orientada a objetos. Houve algumas menções a mencionar que você poderia fazer uso de seu recurso ou algo parecido, mas não no sentido puramente OOP (na verdade, eu realmente não entendi o que a pessoa queria dizer).

Existe alguma verdade nisso; se sim, por que?

gablin
fonte
5
OOP não é um termo bem definido, portanto, discutir se C ++ é ou não adequado é inútil.
Zvrba

Respostas:

31

Como descrito em Então, o que * Alan Kay realmente quis dizer com o termo "orientado a objetos"? , Alan Kay achava que a passagem de mensagens era a parte importante do OOP, mas é a parte que falta ao "C com classes" (que mais tarde se tornou C ++). C ++ é apenas estruturas com um pouco de comportamento, enquanto objetos em Smalltalk ou Objective-C são "inteligentes", pois podem decidir o que fazem com as mensagens enviadas. Se um objeto do tipo Smalltalk receber uma mensagem para a qual não tem uma implementação, ele poderá adicionar uma preguiçosamente, encaminhar a mensagem para outro objeto ou fazer qualquer coisa arbitrária.

O que o C ++ oferece em termos de orientação a objetos são virtualmétodos e polimorfismos envolvendo a maneira como esses métodos são chamados. Quando o compilador vê um tipo de dados (ou class) que possui métodos virtuais, ele cria uma tabela com um slot para cada método virtual. As subclasses que implementam os métodos virtuais colocam suas implementações nos slots corretos; portanto, o código do cliente precisa apenas saber onde na tabela virtual procurar o código a ser executado, em vez de resolvê-lo até a função específica. O que isto significa é que C ++ efetivamente faz ter uma forma de múltipla expedição, embora tudo é implementado no compilador e não é tão capaz quanto um sistema Smalltalk-esque.

Se você considera a passagem de mensagens fundamental para o POO, enquanto você pode fazê-lo com C ++, está longe de ser fácil. OTOH, se você considerar OOP como associação de dados a funções que atuam nesses dados, C ++ está correto.

Comunidade
fonte
8
+1 - mas sempre achei que uma chamada de função era uma maneira razoável de transmitir uma mensagem. É verdade que é uma base de baixo nível, e não uma correção de alto nível para tudo - mas o padrão de objetos ativos mostra que é possível construir a partir dessa base.
213711 Steve314
6
de modo que este se aplica não só para C ++, mas para Java, C #, Object Pascal, etc. E ele acaba sendo que o sistema de mensagens API do Windows é o que Alan entende como a coisa mais importante em OOP, especialmente a forma como ele é tratado pelo Delphi
Trinidad
@ Trinidade correta, exceto C # realmente suporta resolução dinâmica. Espero que seja justo dizer que nossa ideia de OOP mudou ao longo do tempo para contornar a falta de transmissão de mensagens. Ajudou, sem dúvida, por vendedores dizendo que sua tecnologia é definitivamente OOP em face de evidências ...
@ steve314 sim, é. De fato, é assim que o ObjC funciona, um envio de mensagem é traduzido em uma chamada de função que procura e chama a função de método. Pelo que entendi, a passagem dupla é importante.
1
@ Paul: Tendo alguma experiência limitada com a API do Win32, eu não entendo. Qualquer API em que os objetos tenham tamanho variável e onde é necessário chamar primeiro uma rotina para determinar o tamanho do objeto, alocar memória e chamá-lo novamente, falha no meu teste de beleza.
David Thornley
27

Esse tipo de discussão me incomoda porque soa como exegese, pessoas debatendo o significado das Escrituras Sagradas ou a Constituição Americana e o que os autores originais queriam dizer, como se o que pensamos não importasse.

Olha, Alan Kay era / é um cara inteligente, e ele teve uma boa ideia, que se deparou com várias outras boas idéias e encontrou sua realização no Smalltalk e em outras línguas.

Ele não é o Messias, e OOP não é o único e verdadeiro paradigma de programação.

É uma boa ideia, entre muitas. O C ++ tem boas idéias, provenientes da mentalidade OOP? Claro que sim.

Mike Dunlavey
fonte
8

O C ++ suporta OOP, se você definir OOP para significar encapsulamento, herança e polimorfismo.

No entanto, C ++ realmente não se destaca no OOP. Uma razão é que o polimorfismo geralmente depende de objetos alocados por heap, os quais (apesar do uso de ponteiros inteligentes) são mais naturais para trabalhar em uma linguagem de coleta de lixo.

Onde C ++ se destaca, no entanto, é na programação genérica. O C ++ permite criar facilmente código genérico altamente eficiente por meio de técnicas de programação funcional baseadas em modelo.

Charles Salvia
fonte
4

O C ++ emprestou recursos de OOP da Simula. Um ou mais desenvolvedores do Simula IIRC comentaram que C ++ não é o que eles tinham em mente.

O C ++ possui boas ferramentas para abstração, mas é mais uma linguagem de paradigma misto do que uma linguagem orientada a objetos. Os recursos orientados a objetos estão lá, mas você tem opções que não são "OOP estritas".

Um dos "opt-outs" impertinentes que você obtém no C ++ é usar a vinculação antecipada e não tardia nos métodos. Isso não é apenas possível - é o padrão. Em Java, "final" está relacionado, mas mais limpo em alguns aspectos (que especifica a intenção de uma forma que não é apenas sobre como evitar uma sobrecarga de desempenho trivial), e é não o padrão.

De certa forma, o C ++ mostra sinais de ser um experimento inicial que ainda está aqui. Mesmo assim, ainda é uma boa ferramenta, com muitas vantagens que você não obtém em outros idiomas OOP.

Steve314
fonte
2
O C ++ permite não OOP e o C ++ permite OOP, para que uma linguagem seja OO, ela deve permitir OOP, portanto, C ++ é uma linguagem OO.
Trinidad
1
Acredito que Alan Kay, da fama de Smalltalk, disse que C ++ não era o que ele tinha em mente quando cunhou o termo "orientado a objetos". Desde que o C ++ começou como "C com Classes", um enxerto de classes do Simula no C, e nunca fez uma pausa limpa, não é de admirar que pareça um experimento inicial.
David Thornley
1
@ Trinidad: QUALQUER idioma permite POO. Eu já vi bastante código OO interessante no simples e antigo C. Sim, é complicado definir todas as tabelas de métodos virtuais manualmente, mas a linguagem claramente o permite .
precisa
4

Forçar tudo a fazer parte de uma classe não necessariamente gera um ótimo código OO.

Peça a um programador de procedimentos ruim para programar em Java e eles possivelmente levarão uma classe para algum lugar, darão a ele um método principal estático e colocarão 1000 linhas de código nele. Eu sei que já vi.

Java possui uma instrução switch. Eu vi switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }etc. no código C ++ e Java.

O C ++ suporta muitos conceitos de OO, mas seu padrão não é definido por ele, no entanto, acho que depende muito de qual é seu objetivo.

A principal semântica "ruim" em C ++ está permitindo a cópia de construção de classes, pela qual um objeto se transmogrifica em outro. Você pode desativar isso, mas não pode retornar um de uma função. Felizmente, isso é resolvido no C ++ 0x.

CashCow
fonte
3

OOP não é apenas garantir que tudo esteja dentro ou fora de uma classe. É perfeitamente possível escrever código não OO em uma linguagem "puramente OO". Por exemplo, "main" é frequentemente apontado como sendo uma função global, mas inventar uma classe apenas para conter um método principal estático é igualmente não-OO.

C ++ funciona melhor com uma mistura de várias coisas; isso não deve ser surpreendente, pois é assim que a maioria das coisas boas funciona melhor. Frequentemente, a OOP é uma dessas ferramentas muito úteis.

Fred Nurk
fonte
2

O C ++ pode ser usado para OOP, mas não é tão "puro" quanto algo como Smalltalk. O C ++ também permite que você faça não-OOP, e é disso que as pessoas podem estar falando.

Craig
fonte
2

Embora eu discorde do sentimento, é verdade que o sistema de tipos do C ++ não é puro OOP - nem "tudo é um objeto". Os números (em particular) não podem ser estendidos tão prontamente quanto podem, digamos, em Smalltalk. Você não pode redefinir o significado de "2 + 2", por exemplo (embora possa redefinir o significado de "dois + dois").

Mas o que a maioria das pessoas provavelmente quer dizer é que muitas pessoas escrevem código não orientado a objetos em C ++, mas acreditam que, por estarem usando uma linguagem "OOP", estão orientadas a objetos. Isso não é verdade. Mas, na minha opinião, você pode escrever um código imperativo hediondo no Smalltalk e não ser superior a um design decente de OOP em C ++.

Larry OBrien
fonte
1

A objeção perfeitamente válida de Alan Kay ao C ++ era que era uma linguagem macro em cima de C.

A noção de "passagem de mensagem" é simplesmente a idéia de que instâncias de classes são mantidas na memória e que elas expõem métodos que podem ser chamados. A passagem de mensagens é * simulada "em C ++ usando vtables segurando ponteiros para funções.

Dizer que a passagem de mensagens não existe em C ++ é impreciso, o que é mais preciso dizer é que a passagem de mensagens é parte integrante de outras linguagens, como smalltalk e Java, porque a linguagem não está pré-processando uma construção estrangeira e enxertando-a diretamente em C.

Esse é um argumento de design de linguagem altamente semântico que, suspeito, está um pouco além do nível de experiência do questionador.

Dito isto, existem milhares de razões para odiar o C ++ e muito poucas razões para odiá-lo.

Em vez de procurar o martelo perfeito e a unha perfeita, encontre a casa perfeita para construir e depois encontre as ferramentas certas ... que exigem experiência.

Também é importante lembrar que, na programação de sistemas, o que Alan Kay teme não é "pura OOP", é realmente uma força do C ++. Cada um na sua...

bobx
fonte
1
O objetivo C também começou como linguagem macro em cima de C, mas é uma linguagem orientada a objetos.
precisa
1

Na minha opinião, não é tanto uma questão de definição quanto uma questão de usabilidade.

Objetos são uma abstração destinada a facilitar a leitura, gravação e raciocínio sobre programas complexos. Para um programador prático, se uma linguagem atende a todos os critérios de uma definição formal específica de "orientada a objetos" (parece haver várias concorrentes) não é realmente tão importante quanto se as ferramentas que ela oferece são adequadas para pensar sobre seu programa em termos dos referidos objetos - ou seja, colhendo os supostos benefícios de produtividade da OOP.

No C ++, os objetos são abstrações terrivelmente vazadas , forçando os programadores a lidar com questões desagradáveis ​​relacionadas à forma como esses objetos são estruturados na memória - questões que lembram mais a codificação em C direto do que outras linguagens OOP. Por exemplo, o C ++ Frequently Questioned Answers oferece essa crítica (entre outras):

É muito benéfico para um profissional familiarizar-se com sistemas OO diferentes de C ++ e com definições de OO diferentes da trindade "encapsulamento, herança, polimorfismo" interpretada de maneiras especiais, permitindo que C ++ seja considerado "OO". Por exemplo, uma alegação de que um ambiente sem verificação de limite ou coleta de lixo não é um ambiente OO parece ultrajante para as pessoas acostumadas ao C ++. Mas de muitas perspectivas, faz muito sentido. Se alguém pode substituir um objeto, onde está o "encapsulamento"? Se o descarte de um objeto pode levar a referências pendentes ou vazamentos de memória, como o sistema é "orientado a objetos" ? E a capacidade de dizer que tipo de objeto está localizado em um determinado local e horário? Você diz que o software trabalha com objetos - onde eles estão? E se não se pode descobrir, como se deve depurar o software?

O C ++ é orientado a objetos, mas desagradável e incompletamente: seus usuários precisam dedicar muito esforço para garantir que seus dados realmente se comportem como objetos "reais" em vez de bits errados. Dito isto, muitos códigos foram escritos em C ++ ao longo de sua vida útil, a maioria usando classes e envio dinâmico, portanto é algo que você pode usar para OOP prático.

Alex P
fonte
-1 para referenciar o FQA no que deveria ser uma resposta séria. O FQA é um ninho de distorções, meias-verdades e mal-entendidos.
precisa
@DavidThornley A citação em particular é uma distorção, meia-verdade ou mal-entendido?
Alex P
Em algum lugar lá. A alegação de que uma linguagem OO deve ter verificação de limites (às vezes incorporada em contêineres padrão C ++ de qualquer maneira) e coleta de lixo (ponteiros inteligentes são coleta de lixo primitiva) é forçada e não é adequada. A sentença sobre uma linguagem que permite que referências pendentes não sejam orientadas a objetos é claramente uma prova da afirmação flagrante. Estou intrigado com a "capacidade de dizer que tipo de objeto"; o tipo de ponteiro o distribui para objetos sem comportamento virtual e o RTTI o manipula para objetos com comportamento virtual.
precisa
@DavidThornley A alegação do FQA é que uma linguagem OO útil deve ter essas coisas - o que está de acordo com a pergunta que está sendo feita (o C ++ é "adequado"?). Eu acho que uma afirmação sobre definições básicas realmente não aborda isso ... "Capacidade de dizer": um comportamento de erro comum ao acessar um objeto que não está realmente lá, seguindo um ponteiro para alguns dados não inicializados ou sobrescritos anteriormente; e seu programa terá o prazer de interpretar esse lixo e interpretá-lo como dados e, em seguida, seguirá os ponteiros do lixo para outros dados até encontrar um endereço fora dos limites ou ocorrer algum erro grave.
Alex P
No entanto, a citação pelo menos sugeriu fortemente a afirmação de que um idioma sem verificação de limite ou coleta de lixo não é OO e ignorou o fato de que você tem essas coisas em C ++, se quiser. A questão de saber se uma linguagem impede ou não certas classes de erros (por qualquer motivo) é ortogonal à questão de se é OO.
precisa
-1

Há uma razão pela qual Graham Lee teve mais votos positivos aqui. Para reiterar, parece que uma classe C ++ não é realmente um objeto no sentido de que não executa a passagem de mensagens. Eu acho que é isso que atrai bastante as pessoas quando elas estão aprendendo C ++ ou oop. É dito às pessoas que a orientação a objetos é 'this' e, em seguida, é dito que o C ++ faz de maneira diferente. Bem, o C ++ nunca fez OOP de maneira diferente. Se você pensa assim, nunca apreciará as classes C ++ pelo que elas significam, e isso é que elas são apenas uma melhoria no paradigma processual, incorporando abstração e comportamento dinâmico. Portanto, as classes C ++ são processualmente fundamentadas, apenas melhoram o paradigma processual, ou melhor, são uma versão mais avançada de uma estrutura C.

annoying_squid
fonte
Você tem algum motivo real para apoiar seus argumentos? Você parece estar fazendo afirmações e alegando que aqueles que discordam devem estar enganados ou que mudariam de idéia se olhassem para isso de forma diferente ou talvez se compartilhassem sua definição exata de OO.
precisa
Justo. Você pode ler este artigo . Acho que o que eu estava dizendo é que c ++ não é "programação orientada a objetos", no sentido estrito de Alan Kay. No entanto, se você definir OOP como sendo uma estrutura de dados com comportamento, poderá considerar c ++ como OOP. Na minha opinião, embora seja mais preciso visualizar uma classe c ++ como uma abstração de programação processual de nível superior. Uma classe c ++ é muito mais eficiente que um objeto de estilo Kay, mas pior para simultaneidade. Pessoalmente, acho que a classe c ++ é um ótimo design.
annoying_squid
1
Obrigado pelo link, mas apenas explica o que Alan Kay quis dizer. Além disso, eu discordo que o Smalltalk é geralmente considerado o primeiro idioma OO, e a Wikipedia concorda comigo que esse era o Simula, um dos dois idiomas que Stroustrup combinou para formar C com Classes. Estou interessado em sua afirmação de que uma classe C ++ é mais uma abstração de programação processual de nível superior do que um modelo de objeto, mas ainda não entendo por que você pensa assim.
David Thornley
Orientação a Objetos é provavelmente um termo subjetivo, se pudermos concordar com isso. Mas vejo um objeto Kay como uma maneira mais natural de dissociar código e introduzir modularidade simultânea no sentido de que cada objeto desempenha um papel como minicomputadores interagindo através da passagem de mensagens. Sob esse modelo, deve haver pouco ou nenhum código 'entre' b / c. Toda a lógica do programa pode ser expressa como células e mensagens. Em comparação, o uso de 'classes' normalmente requer algum código de cola processual no meio (falta modularidade verdadeira), mas a vantagem é que as classes são muito mais eficientes.
annoying_squid
-1

Steve Yegge disse o melhor :

C ++ é a linguagem mais idiota do mundo, no sentido muito real de ser a menos sensível. Não sabe sobre si mesmo.

O sistema de objetos em C ++ é tão conectado e fixo em tempo de compilação, que é muito distante da noção original de OOP que envolve passagem de mensagens, introspecção, reflexão, envio dinâmico e ligação tardia, entre outras coisas. A única coisa que C ++ e Smalltalk têm em comum são um pouco de vocabulário.

John Cromartie
fonte
De que maneira C ++ é a linguagem menos sensível? O que significa para um idioma ser senciente? Se você quer dizer que não possui capacidade de reflexão, isso é bastante comum e certamente não escolhe C ++ entre uma multidão.
David Thornley
2
Como diabos você poderia dizer que ele disse isso "melhor"? Não faço ideia do que essa citação aleatória significa.
precisa saber é o seguinte
Marcar com +1 dizendo que esse tipo de coisa receberá muitas críticas dos bashers do C ++, mas é preciso dizer - você não pode realmente fazer POO sem reflexão, porque não possui os genéricos para cuidar de coisas horizontais ( aspectos) - ciclo de vida (ativação, descarte), tratamento genérico de erros, proxy genérico, serialização genérica, paralelismo genérico de tarefas - acabam poluindo seu código e quebrando o SoC.
vski 5/06/12
Obrigado. Não acredito que cheguei a -3 por dizer que uma linguagem sem reflexão não é um bom exemplo de POO.
John Cromartie
1
@ JohnCromartie, você poderia falar sobre esse ponto na sua resposta?
precisa