Faço parte de um grupo de pesquisa e aqui temos programadores (ou aspirantes a programadores) de Java, C e C++ e hoje surgiu uma discução sobre as duas linguagens óbvio que todos sabemos que não existe melhor linguagem e sim a que mais se aplica a determinada aplicação a ser desenvolvida, mas seguindo uma linha de vantagens e desvantagens, podemos inferir que o CG e a Portabilidade do Java são pontos bons e a JVM um ponto fraco?
Para escrever software portável não necessáriamente se precisa de máquina virtual, mas em contrapartida a máquina virtual contribui com recursos que pode ou não tornar um projeto mais produtivo.
V
ViniGodoy
Primeiro de tudo. C e C++ são duas linguagens distintas.
Você quer saber em relação ao C ou ao C++?
J
juliocbq
ViniGodoy:
Primeiro de tudo. C e C++ são duas linguagens distintas.
Você quer saber em relação ao C ou ao C++?
aliás, eu também não entendi direito a questão
E
entanglement
guisantogui:
Então gente, mais uma vez vem a grande guerra!!
Faço parte de um grupo de pesquisa e aqui temos programadores (ou aspirantes a programadores) de Java, C e C++ e hoje surgiu uma discução sobre as duas linguagens óbvio que todos sabemos que não existe melhor linguagem e sim a que mais se aplica a determinada aplicação a ser desenvolvida, mas seguindo uma linha de vantagens e desvantagens, podemos inferir que o CG e a Portabilidade do Java são pontos bons e a JVM um ponto fraco?
Vlw gurizada!
Desculpe - é GC (Garbage Collection), CL (Coleta de Lixo) ou CG (Honda?)
V
ViniGodoy
Eu citaria as seguintes (comparação de Java com C++):
Java:
VANTAGENS
Mais fácil de programar: managed code realmente é uma mão na roda;
Melhores relatórios de erros: stacktraces completos;
Melhores IDEs, depuradores e profilers;
Possibilidade de fazer reflexão;
Multiplataforma - o que facilita também montar o ambiente para programar em java (em C, é comum alguém ter compilado algo para plataforma X e você ter que baixar a API, entender o make e compilar o projeto para sua plataforma Y).
Mais fácil de se obter uma aplicação otimizada (o algoritmo de alocação de memória do GC é excelente, e a VM pode otimizar aplicações multi-thread com facilidade);
DESVANTAGENS:
Código fácil de descompilar;
Pouca integração com o sistema operacional (é o preço que se paga por ter uma VM);
Execução não determinística, o que inviabiliza real-time (preço que se paga por um garbage collector);
Baixo controle sobre o consumo de memória;
Sem suporte em diversos dispositivos e SOs;
C++
VANTAGENS
Portabilidade: Suporta um número MUITO maior de plataformas;
Suporta programação genérica;
Muito integrável com o sistema operacional e hardwares externos (ao custo de portabilidade);
Possibilidade de escrever uma aplicação com execução determinística e extremamente enxuta (você pode até mesmo escrever seu próprio algorítmo personalizado de alocação e desalocação de memória, pode saber o custo computacional exato de cada comando que utilizar, etc). Isso o torna ótimo candidato para o mercado de firmwares;
Mais otimizável. Embora o Java saia mais rápido “por default”, você pode chegar a um código no C++ mais rápido que qualquer equivalente em Java, desde que esteja disposto a pagar por isso;
DESVANTAGENS
Mais difícil de se programar;
Mais difícil achar programadores experientes na linguagem;
Erros difíceis de diagnosticar (especialmente os envolvendo templates);
Note que as vantagens que ressaltei acabam posicionando o C++ no local onde ele atua hoje: Em aplicações de tempo real, firmwares e aplicativos que usam recursos específicos dos sistemas operacionais (como a maior parte das aplicações desktop para usuários finais e games).
V
ViniGodoy
Vale ressaltar que algumas coisas são diferenças simplesmente. E podem ser usadas para o bem ou para o mal.
O C++ permite compilação condicional, por exemplo. E permite também a criação de macros.
Isso nem sempre representa um benefício.
Outras vantagens que eu citaria para o C++ é a sobrecarga de operadores e a possibilidade de construção implícita, especialmente válida em aplicações mais matemáticas.
E
entanglement
O que simplesmente abomino no C++ é o recurso de “#include”. Ele, basicamente, é que atende pelos tempos de compilação infernais de programas C++, e pela impossibilidade de você (dado um trecho de programa C++) saber se ele está sintaticamente correto sem fazer a compilação de todas as linhas anteriores. Isso é que faz com que IDEs para C++ não consigam um recurso de auto-complete ou “Intellisense” tão bom quanto as IDEs que lidam com o Java ou o C#.
J
juliocbq
Outra desvantagem do c++ no caso é o mecanismo de herança. Ele faz uma cópia exata dos dados da entidade antecessora, o que produz alguns inconvenientes como de o compilador não saber qual método usar(no caso herança múltipla), bem conhecido como Diamond Problem. Pode ser facilmente evitado com a palavra chave “virtual” ao se herdar entidades.
V
ViniGodoy
O diamond problem veio de uma interpretação perigosa que se tinha de herança, tanto que linguagens atuais a abominaram.
No C++, não existe o conceito forte de interfaces, você tem que contar com a boa vontade do programador para que o recurso saia direito.
O C++ também tem algumas bizarrices nesse quesito. Como herança private e, ainda mais estranho, herança protected.
Uma vantagem do Java é que a sintaxe ainda é muito nova, e portanto, não tem muitas exceções ou coisas esquisitas devido a necessidade de se manter compatibilidade com o passado.
Ela também já foi criada corrigindo os problemas do C++ e tornando padrão várias boas práticas que o C++ tem.
R
Rafael_Afonso
Pessoal:
Deixa eu aproveitar o gancho e me tirem uma dúvida: Qual a função da palavra friend? Se eu me lembro ela afeta o modo de acesso das variáveis/funçoes da mesma forma que public, protected ou private mas agora não me lembro como.
V
ViniGodoy
Se A diz que B é seu friend, então B poderá ver todas as partes privadas de A, como se fossem publicas.
É excelente para fazer DAOs. As classes podem dizer que seus DAOs são friends, para os daos tenham acesso total a seus atributos.
Esse modificador faz muita falta nessas horas.
R
Rafael_Afonso
ViniGodoy:
Se A diz que B é seu friend, então B poderá ver todas as partes privadas de A, como se fossem publicas.
É excelente para fazer DAOs. As classes podem dizer que seus DAOs são friends, para os daos tenham acesso total a seus atributos.
Esse modificador faz muita falta nessas horas.
Me dê um exemplo de como isso poderia ser feito em Java se existisse a palavra friend. Suponha que tenhamos as classes públicas UsuarioBusiness, UsuarioDAO e EmpresaBusiness. E daí eu quero que UsuarioDAO seja acessível apenas para UsuarioBusiness. Como faria?
Isso de restringir o acesso de classes não é o objetivo do projeto Jigsaw, agora prometido para o Java 8?
J
juliocbq
Friends podem ser tanto classes como funções.
Aqui no msdn existe um exemplo interessante a estilo do que o vini citou.
Apesar de eu achar a função friend quebrar o encapsulamento ela acaba sendo extremamente útil.
E
entanglement
O motivo original de existirem “friends” em C++ é porque operadores normalmente são globais (ou então membros de uma classe, mas isso é mais raro).
Então você cria algo como:
publicclassUsuarioBusiness{privateintid;privateStringnome;//Indica que UsuarioDao é friend.friendclassUsuarioDao;publicintgetId(){returnid;}publicStringgetNome(){returnnome;}}
publicclassUsuarioBusiness{publicUsuariocarregar(intid){UsuarioBusinessusuario=newUsuarioBusiness();//Suponha que esse método existe, e acha o RowSet do usuário no banco.RowSetrs=loadFromDataBase(id);//Note que estou acessando propriedades privadas, como se fossem publicas//o hibernate e outras APIs fazem isso por reflexão. Aqui não há reflexão, há code completion e é tudo typesafe.usuario.id=rs.getInt("id");usuario.nome=rs.getString("nome");returnusuario;}}
J
juliocbq
Rafael Afonso:
ViniGodoy:
Se A diz que B é seu friend, então B poderá ver todas as partes privadas de A, como se fossem publicas.
É excelente para fazer DAOs. As classes podem dizer que seus DAOs são friends, para os daos tenham acesso total a seus atributos.
Esse modificador faz muita falta nessas horas.
Me dê um exemplo de como isso poderia ser feito em Java se existisse a palavra friend. Suponha que tenhamos as classes públicas UsuarioBusiness, UsuarioDAO e EmpresaBusiness. E daí eu quero que UsuarioDAO seja acessível apenas para UsuarioBusiness. Como faria?
Isso de restringir o acesso de classes não é o objetivo do projeto Jigsaw, agora prometido para o Java 8?
A seu Exemplo
#include<iostream>usingnamespacestd;classUsuarioDao{friendclassUsuarioBusiness;// aqui a classe friendpublic:UsuarioDao():topSecret(0){}voidprintMember(){cout<<topSecret<<endl;}private:inttopSecret;};classUsuarioBusiness{public:voidchange(UsuarioDao&ub,intx){ub.topSecret=x;}};intmain(){UsuarioDaoud1;UsuarioBusinessub1;ud1.printMember();ub1.change(ud1,5);ub1.printMember();}
Me baseei no exemplo da msdn.
J
juliocbq
No final, a idéia é a do desenho abaixo
E
entanglement
Em C++,
“O amigo de meu pai não é meu amigo”,
“O amigo de meu filho não é meu amigo”, e
“O amigo de meu amigo não é meu amigo”.
Eu chamaria o qualificador “friend”, na verdade, de “boyfriend” ou “girlfriend” (não sei qual é o sexo de uma classe) porque, de fato, o relacionamento em C++ está mais para esse tipo que o de amizade. Mas seria esquisito ter algo em C++ como:
O motivo original de existirem “friends” em C++ é porque operadores normalmente são globais (ou então membros de uma classe, mas isso é mais raro).
Então você cria algo como:
class Complex {
private:
double re;
double im;
public:
Complex (double re, double im) : re(re), im(im) { }
friend Complex operator + (const Complex&, const Complex&);
};
...
// Note que isto é um operador global, mas precisa ter acesso aos membros da classe Complex,
// portanto ela tem de ser declarada como "friend" (amiga) da classe Complex.
Complex operator + (const Complex& a, const Complex& b) {
return Complex (a.re + b.re, a.im + b.im);
}
Isso mesmo. Se a sobrecarga de operador acontecer dentro do encapsulamento(da classe) você não pode usar o segundo parâmetro. Isso também mostra o que comentei sobre quebrar o encapsulamento, mesmo sendo muito útil.
Q
quikkoo
nesse caso por se tratar da própria classe as funções friends nem são necessárias, mas claro, fica a escolha do desenvolvedor, para classes matemáticas ele sempre me foi util quando se precisou sobrecarregar um operador onde o primeiro termo é um tipo primitivo. e.g.:
Em C++,
…
“O amigo de meu filho não é meu amigo”, e
…
Eu chamaria o qualificador “friend”, na verdade, de “boyfriend” ou “girlfriend” (não sei qual é o sexo de uma classe) porque, de fato, o relacionamento em C++ está mais para esse tipo que o de amizade.
A menos que você assista à novela das 8 e veja o que a Stela aprontou
J
juliocbq
quikkoo:
nesse caso por se tratar da própria classe as funções friends nem são necessárias, mas claro, fica a escolha do desenvolvedor, para classes matemáticas ele sempre me foi util quando se precisou sobrecarregar um operador onde o primeiro termo é um tipo primitivo. e.g.:
Um compilador ansi/iso c++ não permitiria sobrecarregar + com dois parâmetros de dentro do escopo da classes, permitiria?
O g++ não permite comigo aqui.
a) Se o operador é binário (operator + por exemplo), e se ele tem declarados 2 argumentos, então ele não recebe o argumento “this” implícito, portanto ele não pode ser membro de uma classe. Ele tem de ser estático ou global.
b) Se o operador é binário, e se ele tem declarado apenas 1 argumento, o outro argumento é o “this”. Nesse caso, ele é obrigado a ser membro de uma classe. É como se
Complex a;
Complex b;
Complex c = a + b;
nós tivéssemos algo como
c = (a. operator +) (b);
E
entanglement
Note que um operador pode ser unário também. Por exemplo, digamos que queiramos criar um operador “-” para a classe Complex. Nesse caso, ou ele é declarado com 1 argumento e é global, ou ele é declarado sem argumentos e recebe implicitamente this.
J
juliocbq
entanglement:
Bom:
a) Se o operador é binário (operator + por exemplo), e se ele tem declarados 2 argumentos, então ele não recebe o argumento “this” implícito, portanto ele não pode ser membro de uma classe. Ele tem de ser estático ou global.
b) Se o operador é binário, e se ele tem declarado apenas 1 argumento, o outro argumento é o “this”. Nesse caso, ele é obrigado a ser membro de uma classe. É como se
Complex a;
Complex b;
Complex c = a + b;
nós tivéssemos algo como
c = (a. operator +) (b);
Com certeza.
Q
quikkoo
aqui compila normalmente e com o parametro ‘-ansi’, pois se trata de uma função idependente, e ñ um metodo da classe Complex, dai nao tem o primeiro parametro, que seria o this, como disse o entanglement
e nesse caso tem mesmo q compilar, pois pode-se colocar essa função (sobrecarga do operador +) fora da classe, mas daí ñ se pode usar o recurso friend
t+
J
juliocbq
quikkoo:
aqui compila normalmente e com o parametro ‘-ansi’, pois se trata de uma função idependente, e ñ um metodo da classe Complex, dai nao tem o primeiro parametro, que seria o this, como disse o entanglement
e nesse caso tem mesmo q compilar, pois pode-se colocar essa função (sobrecarga do operador +) fora da classe, mas daí ñ se pode usar o recurso friend
t+
sim, você tem razão. A palavra chave friend já implica que é apenas a declaração de um método que já existe.
M
matheuslmota
Bem, aproveitando a thread, eu gostaria de saber se existe possibilidade de se conseguir a portabilidade em um aplicação com C++.
B
bezier_curve
Baixe os fontes de uma aplicação C++ como o próprio JDK (em http://download.java.net/jdk6/source/ ).
Você vai ver que ele foi portado para as seguintes arquiteturas: x86, Sparc, x64, e ia64, tudo em um único fonte, para Windows, Linux e Solaris.
Obviamente isso demandou um monte de esforço (centenas de milhares de horas-homem de testes, desenvolvimento, especificação e gerenciamento).
Q
quikkoo
sim e não, tudo depende doq vc considera ser portável, e o quão portável vc deseja…
programas já compilados em c ou c++ geramente ñ funcionam em plataformas diferentes, e isso não é considerado portável, mas se vc considerar que uma recompilação sem qlqr alteração no código é algo portável, então temos um código em c ou c++, basta um conhecimento de quais bibliotecas usar em seu projeto para que isso aconteça
acho q portabilidade não é mais (ou nunca foi) um conceito onde é ou não é, mas sim até q ponto é portável, pois sobre certas circuntâncias nem mesmo códigos java e dot.net são portáveis, tem até uma brincadeira: “compile once, debug everywhere”
flw, t+
J
juliocbq
Sim, e posso te dizer que um fonte planejado, usando ansi/iso c++ pode rodar em uma gama de dispositivos muito maior que a do java.
Existem bibliotecas que se propõem a gerar interfaces portáveis como swing do java, que são os casos do wxwidgets e qt, além de muitas outras claro.
Não precisa muito esforço não.
A questão é claro, como os compiladores c++ geram instruções nativas, um executável win não vai rodar em ambiente linux. Então o que pode ser totalmente portável é o código fonte.
No final das contas essa é uma das funções do jit em uma máquina virtual.
Não se esquecer de:
a) Usar bibliotecas que foram portadas para vários sistemas operacionais e plataformas, como o Boost e o Qt,
b) O que não estiver na biblioteca e tiver de ser específico para um determinado sistema operacional deve ser segregado em uma classe separada,