C++ e java

24 respostas
M

gostaria de discutir com vocês, diferenças de linguagem e uso de c++ e java.

vantagens e desvantagens de cada um em cada caso.

é muito claro que não há como comparar no geral as duas linguagens, já que têm aplicações diferentes.

por isso mesmo, seria bom discutir casos pontuais interessantes!

24 Respostas

M

sugiro iniciar a discussão pela questão das funções inline, que existem em c++ e são ausentes em java.
e como isso prejudicaria a eficiência da estratégia de encapsulamento da orientação a objetos.

o que acham?

T

Funções inline são um detalhe de implementação e podem ou não ser usadas pelo compilador C++.
Não é que sejam “ausentes” em Java; apenas a palavra-chave “inline” não existe em Java.
No Java o “Just-In-Time Compiler” cria automaticamente funções inline quando elas são necessárias.
Portanto isso não é uma diferença muito significativa, na verdade.

O que digo que é significativo são duas coisas muito importantes:

  • Herança múltipla;
  • Templates.
peczenyj

[flames]Sobrecarga de Operador[/flames]

T

Uma coisa que acho desajeitada em C++ é que não existe reflection, tal como estamos acostumados em Java e .NET.
Você é obrigado a usar alguns truques chatos no C++ para ter um décimo da capacidade de reflection do Java e .NET.

M

interessante!

o que é o conceito reflection?

(desculpem, mas não conheço nada de java. até por isso mesmo quis criar esse tópico.)

T

Vou dar um exemplo.
Digamos que você quisesse, em C++, escrever um método que recebesse um objeto de qualquer classe, e conseguisse listar os métodos da classe à qual pertence esse objeto, sem ter o código-fonte dessa classe. (Esse tipo de coisa é muito comum e usado em Java).
Isso não se pode fazer em C++* mas é possível fazer em Java.

(Não estou dizendo que não é possível determinar a classe de um objeto passado como um parâmetro void* em C++. Isso é possível, usando-se dynamic_cast<> e checando o valor de retorno. Por exemplo:

bool recebeuIntPtr (void *ptr) {
    return dynamic_cast &lt;int *&gt; (ptr) != 0;
}
...
int x; string y;
cout &lt;&lt; recebeuIntPtr (&x) &lt;&lt; endl; // imprime "true"
cout &lt;&lt; recebeuIntPtr (&y) &lt;&lt; endl; // imprime "false"

Mas entre determinar a classe (que exige do programa apenas um dynamic_cast) e determinar os métodos da classe sem ter o código-fonte disponível (que é algo possível em Java mas não em C++) vai uma grande distância.

M
  • templates são uma ferramenta muito poderosa mesmo! quer dizer que elas não existem em java? quais as saídas adotadas?

  • sobrecargas de operadores são muito úteis e elegantes mesmo. ainda assim não são completamente indispensáveis. (são?)

  • herança múltipla é algo que de qualquer forma, ao que parece, deve ser usado com moderação. há vários problemas como por ex. ambiguidade ou duplicação de atributos (ao invés da herança diamante). mas (pela minha falta de experiência prática) não saberia como deixar de usá-la às vezes.

  • o “Just-In-Time Compiler” é um recurso padrão do java? tem algum link para discussão ou texto pequeno para eu poder conhecer melhor? :smiley:

M

thingol, muito interessante (e útil!) :smiley:

“reflection” é realmente um ponto a se considerar…

ViniGodoy
thingol:
Não é que sejam "ausentes" em Java; apenas a palavra-chave "inline" não existe em Java.

Acho que também vale citar que, na maior parte dos casos, o compilador é mais eficiente para descobrir o que pode ser inlined do que os seres humanos. Aliás, boa parte dos compiladores modernos simplesmente ignora a palavra reservada e faz ele mesmo o inlining.

O java só oficializou isso.

O que me irrita profundamente no C++ é que o compilador é extremamente burro em alguns aspectos (geralmente herdados do C) e inteligentíssimo em outros (templates). Por exemplo, muito chato você ter que dar diretivas de compilação para resolver referências cíclicas em headers.

Também não gosto do fato do int (e outros tipos primitivos) não terem um tamanho padrão. Já tentaram combinar 2 bibliotecas multi-plataforma numa única aplicação? Você acaba com 2 defines uint32 que fazem exatamente a mesma coisa. Claro, isso é porque o int tem o tamanho padrão de "uma palavra". Mas isso já não ocorre com o long que, depois da entrada dos 64 bits, ficou realmente exotérico.

Ah sim, não dá para esquecer também que por padrão os construtores do C++ operam de maneira implícita. Ou seja, uma classe com um construtor que recebe um único valor pode trabalhar assim:

class Rational 
{
   double value;
   public Rational (double _value) : value(_value) 
   {
   }
   //blablabla
}; //&lt;-- esse ; também é fonte de irritação

void calcula(Rational x) {
   //faz qualquer calculo
}

Rational x = 2; //Construção implícita
calcula(10.2); //Construção implícita

Para forçar a construção explícita, você deve colocar a palavra "explicit" antes do construtor.

Deixando de reclamar um pouco, eu gosto muito da forma como o C++ lida com constness. É um pouco chato de programar, mas é um recurso que acho muito bacana.

T

Quando o template usa apenas nomes de classes como parâmetros (template <typename T> …) há algo semelhante em Java que é o recurso de “generics”. Entretanto, diferentemente dos templates, há uma série de regras e restrições no Java que tornam o seu uso um pouco complexo (embora possa confessar que em C++ os templates podem ser bem difíceis de entender também).

Foi proposto que se pudesse fazer uma sobrecarga limitada de operadores em Java, mas isso gerou mais calor e controvérsia que outra coisa, e dificilmente será implementado em futuro próximo.

Há algo semelhante em Java, mas bem limitado, que é o uso de “interfaces” (que são semelhantes a classes bases abstratas do C++, mas mais restritas ainda).

  • o “Just-In-Time Compiler” é um recurso padrão do java? tem algum link para discussão ou texto pequeno para eu poder conhecer melhor? :D

De certo modo, todas as implementações “profissionais” do Java para desktop têm JIT, como são o caso das implementações da Sun, da BEA, e da IBM.
Andre_Brito

Opa.
Não sou aquele programador nato em C++ (como o thingol e o ViniGodoy), mas dou meus pulos :stuck_out_tongue:

Uma coisa que eu sinto falta em Java, que tem no C++ são as diretivas de preprocessamento (acho que é assim que se escreve, né?).
Algumas vezes eles são tão úteis. Outras vezes eles só servem pra confundir o código. Como esse:

include <iostream> 
#include <sstream> 
#include <algorithm> 
#include <vector> 
#include <string> 
#include <map> 
#include <set> 
#include <queue> 
#include <stack> 
#include <complex> 
#include <cstdio> 
#include <cassert> 
#include <cmath> 
#include <ext/hash_map> 
#include <ext/hash_set> 
using namespace __gnu_cxx; 
using namespace std; 

#define REP(i,n) for(int i=0,_n=(n);i<_n;i++) 
#define FOR(i,a,b) for(int i=(a),_b=(b);i<_b;i++) 
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--) 
#define FORE(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it) 
template<class T> inline int sz(const T& c) { return c.size(); } 
typedef long long LL; 
#define inf [telefone removido] 
#define eps 1e-9 
#define maxn 2010

Fonte: TopCoder.

Aaaaaaaargh. Como alguém pode entender isso?

peczenyj

Nada te impede de usar java + pre processador C :wink:

Andre_Brito

Tem razão. Desconhecia esse tipo de coisa :slight_smile:

Abraço.

peczenyj

No meu antigo emprego tinhamos varios jpp com varias diretivas tipo #ifdef para compilar codigo de acordo com algumas definições. Era util para desligar certas funcionalidades.

ViniGodoy

Diretivas de pre-processamento para fazer macros geram problemas exotéricos. Não é a toa que hoje deve-se usar inline no lugar de macros.
Considere isso aqui:

é uma macro para descobrir quem é o maior, certo? Ela até funciona de vez enquando, mas veja o que acontece se você testar:

O código é substituido por:

Note que b foi somado 2 vezes, mas com a sintaxe original o programador tinha a intenção de somar apenas uma. O tipo de bug que você levará meses para descobrir.

Além disso, constantes na forma:
#define CONSTANTE 10

Por não serem tipadas, são menos passíveis de otimização. Como também não estão presentes em tabelas de símbolos, são mais difíceis de depurar ou de analisar num crash dump.

Agora, já vi macros usadas para simplificar código C, que ficaria muito complexo sem usa-las. Especialmente quando se fala em tratamento de erros.

ViniGodoy

Uma das coisas que gosto na comunidade C++ é que, pelo fato do C++ ser uma linguagem que dá mais responsabilidade do programador e procura não restringi-lo, existe muito mais gente com senso crítico.

O C++ contém uma série de recursos que são perigosos, mas não foram barrados por resolver problemas específicos. A decisão final fica para o programador. Uma decisão errada pode custar caro e, em muitos casos, não há soluções 100% corretas. Isso força o sujeito a pensar um pouco mais, e ter uma visão menos purista sobre o software.

Por outro lado, essa também é uma desvantagem do C++. Quando estou estudando uma API nova, constantemente tenho a sensação de estar caminhando num campo minado. Existem alguns erros que são obscuros (como o da macro, que postei no meu post anterior).

Aqui temos uma aplicação de carga que deve rodar por centenas de horas a fio. As dores de cabeça que tivemos com memory leaks ou pequenos detalhes são realmente indescritíveis.

Ainda falando da comunidade, também acho ruim muito programador Java falar mal do C++ sem antes conhecer a STL ou a boost. É como falar mal do java sem antes ter sequer visto qualquer classe fora do pacote java.lang.

Da mesma forma, acho chato ver o pessoal do C++ falando mal do Java sem conhecer o que uma VM com compilador JIT é capaz de fazer.

fantomas

Concordo com o ViniGody, aliás se houvesse uma linguagem perfeita para todos os casos não haveria necessidade de outras linguagens.

Vcs poderiam dizer (na opinião de vcs) onde o C++ é mais utilizado hoje em dia? A impressão que tenho é que ele é utilizado em quase tudo semelhante ao Delphi, talvez um pouco menos.

Abraços

ViniGodoy

Talvez um pouco menos?

Só para citar mercados que o C++ existe, onde não há Delphi:

  1. Jogos, seja para computadores ou consoles;
  2. Aplicativos de multi-mídia (players de vídeo, codecs, etc);
  3. Aplicativos para gerência de sistemas operacionais (desfragmentador de disco, anti-virus, etc);
  4. Software embarcado;
  5. Aplicativos para Macintosh;

Entre outros…

fantomas

Obrigado pela resposta viniGodoy.

Abraços

Andre_Fonseca

oi

Eu não programo em C desde o meu primeiro emprego, mais de 7 anos atrás… acho que estou um pouco enferrujado… 8)

naquela época eu usava isso e era muito rápido para fazer umas consultas SQL complexas no banco…

eu nunca vi algo do tipo SQL embutido no código Java, e acho que nos dias de hoje talvez isso não seja mais considerado uma boa prática

:roll:

Andre_Brito

Concordo em gênero grau e número.
C++ parece que libera o programador a pegar o caminho que ele quiser. Explorar o computador por completo. Isso sim é aventura :slight_smile:

Outra aplicação de C++ (e C também), são em drivers.

Abraço.

T

Falando da Boost, estou o usando em um projeto em que, por incrível que pareça, não tive de usar uma única API do Windows; tudo era adequadamente encapsulado pelo Boost. A parte de threads, timers, estruturas de dados complexas e sockets assíncronos foi toda feita só com o Boost, e poderia até converter o programa para Unix sem grandes problemas.

Dá para, usando um único “#include” do Boost (#include <boost/shared_ptr.hpp>), programar em C++ como se fosse em Java, até sem eu me preocupar com “delete” de objetos criados com “new”.

ViniGodoy

Eu não vivo mais sem smart pointers. Desde que li o livro do Alexandrescu, isso aí mudou minha vida.
Quem quiser conhecer mais, tem a série de artigos do Bruno Sanches:

fantomas

André Fonseca:
Eu não programo em C desde o meu primeiro emprego, mais de 7 anos atrás… acho que estou um pouco enferrujado…

naquela época eu usava isso e era muito rápido para fazer umas consultas SQL complexas no banco…

eu nunca vi algo do tipo SQL embutido no código Java, e acho que nos dias de hoje talvez isso não seja mais considerado uma boa prática

Se não me engano deve ter uma equipe na Unisys que utiliza Pro*C para fazer acessos na base de dados Oracle até hoje, confesso que fiquei um pouco impressionado em ver o quão diréto a coisa éra feita.

É lógico que perguntei o porque disso, disseram que para exportar dados em arquivos texto e fazer calculos o Pro*C éra mais rápido.

flws

Criado 6 de novembro de 2008
Ultima resposta 7 de nov. de 2008
Respostas 24
Participantes 7