CPP
C plus plus versus Java
Principais Diferenças
•
•
•
•
Herança múltipla
Destructores e garbage colector
Override de operadores
Máquina virtual
•
•
•
•
•
•
•
•
•
•
•
Templates e genéricos
Referências e ponteiros
Métodos virtuais e classes virtuais
Conversão implícita de tipos usando construtores
Incialização de arrays
Listas de inicialização de membros
Directivas de pre-processamento
Declaration and implementation
Bibliotecas (STL)
Break e continue sem labels, for each
Syntaxe
C++ Hello World
#include <iostream>
using namespace std;
void hello() {
cout<<“Hello Wordl!”;
}
int main(){
hello();
}
Máquina virtual
• O java normalmente corre numa máquina
virtual enquanto que o compilador de C++
gera código máquina.
Herança múltipla
• Uma pessoa pode ser simultaneamente um
estudante e um trabalhador. C++ permite
herança múltipla.
• C++
classe TrabalhadorEstudante: public
Trabalhador, public Estudante {
…
}
Pode gerar problemas se houver métodos comuns a
trabalhador e a estudante, mas tal pode se resolver
por chamadas explicitas do tipo
Trabalhador::metodo1(…) ou
Estudante::metodo1(…)
se a classe estiver a ser utilizada como uma das
classes base não há ambiguidade.
Herança múltipla
• Java
Classe TrabalhadorEstudante extends pessoa
implements Trabalhador, Estudante{
….
}
Obriga e rescrever os métodos de trabalhador e de estudante,
embora este possam chamar implementações de classes
concretas de trabalhador e de estudante.
Ou
Classe TrabalhadorEstudante extends pessoa {
Trabalhador trabalhador;
Estudante estudante;
….
}
Mas tal não permite redefinir facilmente métodos da classe
Trabalhador ou Estudante.
Garbage colector e destructores
• Em java as variáveis são removidas da memoria pelo
garbage colector quando não estão a ser utilizadas.
• Em C++ as variáveis locais são automaticamente
eliminadas, mas variáveis criadas com o operador new o
malloc() tem de ser explicitamente libertadas utilizando
o delete ou free()
Destrutores
File “pessoa.h”
class Pessoa {
private:
nome char*;
public:
Pessoa(nome char *);
~Pessoa();
char *getNome()
{return nome;};
}
File “pessoa.cpp”
#include “pessoa.h”
Pessoa::Pessoa(nome char *){
this->nome = new
char[strlen(nome)];
strcpy(this.nome, nome);
}
Pessoa::~Pessoa(nome
char *){
cout<<“destruindo uma
Pessoa\n”
delete nome;
}
Destrutores
• File “main.cpp”
• #include “pessoa.h”
main(){
Pessoa pessoa(“Joaquim”);
cout<<pessoa.getNome();
cout<<endl;
}
• Resultado
Joaquim
destruindo uma Pessoa
Overload de operadores
String& String::operator+(conts
#include <string.h>
String &s) conts {
String&
String *result = new
String::operator+=(conts
String(this);
String &s) {
// Copia cada ums dos atributos
len+=s.len;
// da String.
char *p= new char[len+1];
result += s;
strcpy(p,str);
// Assume que um novo char array
// foi alocado.
strcat(p,s.str);
return *result;
delete str;
}
str=p;
return *this;
Todos os operadores podem ser
redefinidos menos o “::”, “.*”, “.” e “?:”
}
Código de teste:
String aux(“Hello”);
aux+=“World\n”;
cout<<aux;
Código de teste:
String aux1(“Hello”);
String aux2(“World\n”);
cout<< aux1+aux2;
Operator overloading
• O uso de operadores resulta em código mais compacto.
• No entanto código mais compacto é normalmente
mais difícil de ler.
• Overload de operadores pode levar a código confuso
(devido a redefinições não esperadas).
• Uma descrição textual é normalmente mais descritiva
que um operador.
• Overload complica o compilador
• Por estas razões, não é suportado pelo java.
• No entanto o overload de operadores pode ser útil
desde que bem utilizado.
Templates e genéricos
Template <class Type>
Type min(Type a, Type b)
{
return (a<b)?a:b;
}
Uma chamada da forma:
int a=3, b=4;
cout<<min(a, b);
Queria uma instância do código da forma:
int min(int a, int b) {
return (a<b)?a:b;
}
Uma chamada da forma:
double b=3.2, b=4.7;
cout<<min(a, b);
Queria uma instancia do código da forma:
double min(double a,
doube b) {
return (a<b)?a:b;
}
Existem duas versões da mesma função
ao contrário do mecanismo de
apagamento do java.
Referências e ponteiros
Java
•
Em java todas as variáveis
correspondem a
apontadores para objectos
com excepção dos tipos
primitivos.
•
C++ os objectos são
implementados de forma
semelhante a estruturas.
Apontador tem de ser
criados explicitamente.
•
Ponteiros em C++ podem
ser usados como em C,
por exemplo com
aritmética de ponteiros.
Conta conta = new
Conta(100);
Conta conta2 = conta; //referencia
para conta
System.out.println(conta.getSaldo(
));
C++
Conta conta(100);
Conta conta2 = conta;
// cópia membro a membro de conta
cout<<conta.getSaldo();
– Ou
Conta *conta = new Conta(100);
Conta *conta2 = &conta;
cout<<(*conta).getSaldo();
Referências C++ (&)
•
Referências em C++
class Artigo {
Revista &revista;
Autor &autor;
Artigo(Autor &autor, Revista &revista);
}
Escondem ponteiros mas deixa de ser necessário usar “*”. Exemplo:
autor.nome = “João”
em vez de
(*autor).nome = “João” //autor não é um ponteiro
Tem de ser incializadas e depois disso não podem apontar para outros
objectos. Tal não acontece com as referências em Java. Ao contrário do
java os operadores = e == referem-se ao objecto e não ao ponteiro.
int &refval = val; // Ok
int &refval; // error
Referências java
Java
C++
class Artigo {
class Artigo {
Revista revista;
Autor autor;
Revista *revista;
Autor *autor;
Artigo(Autor autor,
Revista revista)
Artigo(Autor *autor,
Revista *revista)
{
{
this.autor=autor;
this.revista=revista;
this->autor=autor;
this->revista=revista;
}
}
void println() {
System.out.println(
autor.nome);
System.out.println(
revista.nome);
}
}
void println() {
cout<<autor->nome;
cout<<revista->nome;
}
}
Métodos virtuais
Em C++ apenas os métodos com a keyword
virtual podem ser redefinidos.
•
Java
class Conta {
public final float
getSaldo();
public float deposito();
public float
levantamento();
}
• C++
class Conta {
public:
float getSaldo();
virtual float deposito();
virtual float
levantamento();
}
Conversão implícita
Em Java conversão implícitas
são efectuadas: nos tipos
primitivos de char até double;
de uma subclasse para uma
superclasse. Exemplo:
static double
somaAAA(double x, double
x);
int x=3; long z=3;
somaAAA(x,z);
Ou
dump(Conta x);
ContaAOrdem conta = new
ContaAOrdem(100);
Dump(conta);
Em C++ quando estas conversões não
são possíveis são testadas
conversões definidas pelo utilizador
baseadas em construtores e
operadores de conversão. Exemplo:
classe SmallInt {
private: int value;
public:
SamllInt(int x) {value = x;}
operator int() {return
value;}
}
extern SmallInt xpto(SmallInt s);
void main() {
cout<<xpto(34);
// converte 34 em SamlInt, e
SamlInt em int para enviar para
cout
}
Cast
•
Em Java os type cast são
verificados em tempo real.
ContaOrdem extends Conta {
/* code */
}
Conta conta = new
ContaOrdem(100);
// Run time checked
ContaOrdem contaOrdem =
(ContaOrdem)conta;
•
C++ tem vários tipos de type casts.
ContaOrdem: Conta {
/* code */
}
Conta *conta = new ContaOrdem(100);
// C style no run time check
Conta *contaOrdem1 =
(ContaOrdem)conta;
// No run time check
ContaOrdem *contaOrdem2 =
static_cast<ContaOrdem>(conta);
// Run time checked
ContaOrdem *contaOrdem3 =
dynamic_cast<ContaOrdem>(conta);
Arrays: incialização de membros
• Em java os membros dos arrays são por defeito
incializados a null.
• C++ podemos inicializar os arrays com outros
objectos.
String ar1[] = {“phoenix”,”crane”};
String ar2[] = {String(), String(1024),
String(“string”)};
String ar3[] = {1024, String(512)};
Operador delete []
• Se aplicarmos o operador delete a um array apenas o
primeiro elemento é libertado da memoria. Para arrays é
necessário utilizar o operador delete []. No entanto não é
necessário especificar o tamanho do array que é
armazenado pelo new.
• Exemplo:
String aux = new String[100];
…..
delete aux; //errado!!!
delete [] aux; //correcto!!!
Listas de inicialização de membros
•
Java
classe contaOrdem extends conta
{
contaOrdem(float v) {
super(v);
}
}
é chamado o constructor do
super classe como a primeira
linha do corpo do constructor.
•
C++
classe contaOrdem: conta,
aplicação {
{
contaOrdem(float v):
conta(v), aplicação()
{}
}
}
a chamada aos constructores
das super classes é feita numa
lista antes do corpo do
constructor. Notar que podem
ser chamados vários
constructores.
Listas de inicialização de membros
•
Java
classe Autor {
Autor(String n) {…}
}
….
classe Artigo {
Revista revista;
Autor autor;
Artigo(String autor,…) {
autor = new
Autor(autor);
}
•
classe Autor {
Autor(char *n) {…}
}
….
classe Artigo {
Revista revista;
Autor autor;
Artigo(char *n,…):
autor(n) {}
}
•
}
O atributo autor é inicialmente
inicializado com null, e só dentro
do constructor é que o seu valor
final é definido.
C++
•
O atributo autor não é um ponteiro
e portanto não pode ser
inicializado a null. Tem de ser
inicializado com na lista de
incialização de membros.
Tal podia ser resolvido declarando
autor como um ponteiro.
Directivas de pre-processamento
•
•
C++ permite directivas de pre-processamento como no C
Exemplo1:
#include <iostream>
#include “my_header.h”
•
Exemplo2:
#ifndef STRING_H
#define STRING_H
…..
#endif
•
Exemplo3:
#ifdef win32
…..
#endif
#ifdef sun3
…..
#endif
Declaração e implementação
•
No ficheiro “conta.h”
•
No ficheiro “conta.cpp”
#include “conta.h”
class Conta{
float valor;
float taxa;
long numero;
void lançaJuros();
void deposito(float x);
void levantamento(float
x);
}
void Conta::lançaJuros(){
valor+=valor*taxa;
}
void Conta::deposito(float x){
valor+=x;
}
void Conta::levantamento(float x){
valor-=x;
}
Sintaxe
• Uma classe C++
class x: superclasse1, superclasse2 {
private:
int x;
float y;
public:
rtype método1(args);
rtype método2(args);
protected:
rtype método3(args);
}
Download

17-CPPvsJava-08