2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

54
1 2002 LCG/UFRJ. All rights reserved. Tópicos em Tópicos em C++ C++ Claudio Esperança Paulo Roma Cavalcanti

Transcript of 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

Page 1: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

1 2002 LCG/UFRJ. All rights reserved.

Tópicos em Tópicos em C++ C++

Claudio EsperançaPaulo Roma Cavalcanti

Page 2: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

2 2002 LCG/UFRJ. All rights reserved.

Classes e ObjetosClasses e Objetos

• C++ é mais do que C com uns poucos sinos e apitos adicionais.

• O mecanismo básico para atingir programação orientada a objeto em C++ é o conceito de classe.▪Fornece formas de encapsulamento e

proteção de informação.▪Permite reutilização de código.

Page 3: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

3 2002 LCG/UFRJ. All rights reserved.

O que é OO?O que é OO?

• Programação orientada a objeto foi o paradigma dominante dos anos 90.

• Criou o conceito de objeto, que é um tipo de dado com uma estrutura e um estado.▪Cada objeto define um conjunto de

operações que podem acessar ou manipular esse estado.

▪Tipos definidos pelo usuário devem se comportar da mesma maneira de tipos pré-definidos (fornecidos pelo compilador).

Page 4: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

4 2002 LCG/UFRJ. All rights reserved.

Tipos de DadosTipos de Dados

• Um tipo básico de dados de uma linguagem, como inteiro, real, ou caractere, fornece certas coisas:▪Podem-se declarar novos objetos, com

ou sem iniciação.▪Pode-se copiar ou testar quanto à

igualdade.▪Pode-se executar a entrada e a saída de

dados com esses objetos.

Page 5: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

5 2002 LCG/UFRJ. All rights reserved.

ObjetosObjetos

• Um objeto é uma unidade atômica.▪Não pode ser dissecado por um

programador.• Proteção de informação torna os

detalhes de implementação inacessíveis.• Encapsulamento é o agrupamento de

dados, e operações que se aplicam a eles, para formar um agregado.▪Mas escondendo a os detalhes de

implementação.• Uma classe é o mesmo que uma

estrutura, mas com os membros protegidos por default.

Page 6: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

6 2002 LCG/UFRJ. All rights reserved.

EncapsulamentoEncapsulamento

• O princípio de atomicidade é conhecido por encapsulamento. ▪ O usuário não tem acesso direto às partes de

um objeto ou a sua implementação. ▪ O acesso é feito indiretamente, através de

funções fornecidas com o objeto.• É uma forma de imitar a vida real.

▪ Aparelhos eletrônicos possuem o seguinte aviso: “Não abra – não há partes consertáveis por um usuário”.

▪ Pessoas sem treinamento que tentam consertar equipamentos com esses avisos acabam quebrando mais do que consertando.

Page 7: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

7 2002 LCG/UFRJ. All rights reserved.

Reutilização de CódigoReutilização de Código

• A idéia é usar os mesmos componentes sempre que possível.

• Quando o mesmo objeto é a solução fica fácil.▪O difícil é quando se necessita de um objeto

ligeiramente diferente.• C++ fornece diversos mecanismos para

isso.▪Se a implementação for idêntica exceto pelo

tipo básico do objeto, pode-se usar uma template.

▪Herança é o mecanismo que permite estender a funcionalidade de um objeto.

Page 8: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

8 2002 LCG/UFRJ. All rights reserved.

ClassesClasses

• Classes são usadas para encapsular informação.

• Já que as funções que manipulam o estado do objeto são membros da classe, elas são acessadas pelo operador “.”, como em uma estrutura de C.

• Quando se chama uma função de uma classe, na realidade se está passando uma mensagem para o objeto.

• A diferença básica entre OO de C++ e o velho C é puramente filosófica: em C++ o objeto tem o papel principal.

Page 9: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

9 2002 LCG/UFRJ. All rights reserved.

Para Não Esquecer JamaisPara Não Esquecer Jamais

• Se você deseja usar OO, acostume-se a esconder todos os dados das classes.▪C++ não é uma linguagem para

preguiçosos. • Para isto existe uma seção de dados

privados.▪O compilador se esforçará ao máximo para

mantê-los inacessíveis ao “mundo exterior”.• Toda classe possui um construtor e um

destrutor, que dizem como uma instância do objeto deve ser iniciada e destruída.▪Procure escrevê-los sempre. Evite defaults.

Page 10: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

10

2002 LCG/UFRJ. All rights reserved.

class memoryCell {public:

memoryCell ( ) { value = 0; }int read ( ) const { return value; } void write ( int x ) { value = x; }

private:int value;

};

Exemplo BoboExemplo Bobo

Construtor

value está

protegido

Page 11: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

11

2002 LCG/UFRJ. All rights reserved.

Uso da ClasseUso da Classe

main ( ) {memoryCell m;

m.write ( 5 );cout << “Conteúdo da célula é: “

#if 1<< m.read ( )

#else << m.value

#endif

<< ‘\n’;return 0;

}

Instancia a classeArmazen

a um valor

Maneira corretaErro!!!

value é privado!!

!

Diretiva de pré-

processamento

Page 12: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

12 2002 LCG/UFRJ. All rights reserved.

InterfaceInterface

• A interface descreve o que pode ser feito com o objeto.▪ Necessita de uma boa convenção de nomes.▪ Exemplo: primeira letra de nome de classe ou

função minúscula, demais palavras do nome com primeira letra maiúscula (sem “_”).

▪ memoryCell.▪ Dados: ponteiros com prefixo ptr e pode usar

“_”.▪ Constantes e tipos enumeráveis em caixa alta:

◦ GL_FLOAT, GLUT_DOUBLE;▪ Prefixo com o nome do pacote.

◦ glLoadIdentity(), glVertex3f.

Page 13: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

13 2002 LCG/UFRJ. All rights reserved.

DocumentaçãoDocumentação

• É fundamental uma documentação mínima em todo o arquivo de um sistema.

• Existem ferramentas muito boas de domínio público, como o Doxygen.▪Basta colocar diretivas na forma de

comentários na própria interface.▪É melhor acrescentar as diretivas

durante a confecção da interface para não ter de voltar depois de “má vontade”.

Page 14: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

14

2002 LCG/UFRJ. All rights reserved.

Interface Interface memoryCellmemoryCell

// memoryCell.h

// evita incluir a interface de novo se ela já foi // incluída por outro arquivo.

#ifndef __MEMORY_CELL__#define __MEMORY_CELL__

/** * A very simple interface for a generic class. * Doxygen will generate the documentation, * in html, rtf and/or latex automatically. */class memoryCell { public:

/** empty construtor. * Sets the content of this cell to value. * * @param value new value for this cell. */memoryCell ( int value = 0 );

/// destrutor. Não faz nada.~memoryCell ( ) { }

Page 15: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

15

2002 LCG/UFRJ. All rights reserved.

Interface Interface memoryCellmemoryCell

/** the correct way of returning the content of this cell. * @return the content of this cell. */

int read ( ) const; /** sets a new value for this cell. * @param x new value. */

void write ( int x );

private: /// holds the content of this cell. int cell_value;

};#endif

Não altera dados desta classeAltera

dados desta classe

Page 16: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

16 2002 LCG/UFRJ. All rights reserved.

ImplementaçãoImplementação

• A implementação contém os detalhes de como a interface foi codificada, de forma a atender as especificações do projeto.

• As declarações dos nomes das funções ficam na declaração da classe e as implementações são definidas depois, normalmente num arquivo separado (.C, .cpp, ou .cc).▪Usam a sintaxe de função mais o nome

da classe e o operador de escopo “::”.

Page 17: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

17

2002 LCG/UFRJ. All rights reserved.

Implementação Implementação memoryCellmemoryCell

// memoryCell.C

#include memoryCell.h

memoryCell::memoryCell ( int value ) { this->cell_value = value;

} int memoryCell::read ( ) const {

return this->cell_value; } void memoryCell::write ( int x ) {

this->cell_value = x; }

Construtor

getter

setter

Membro desta classe

Page 18: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

18 2002 LCG/UFRJ. All rights reserved.

Construtores e DestrutoresConstrutores e Destrutores

• O construtor diz como o objeto é declarado e iniciado.▪Se a iniciação não casar com nenhum

construtor, o compilador reclamará.• O destrutor diz como o objeto será

destruído quando sair de escopo.▪No mínimo deve liberar a memória que foi

alocada por chamadas “new”no construtor.▪Se nenhum destrutor for declarado será

gerado um default, que aplicará o destrutor correspondente a cada dado da classe.

Page 19: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

19 2002 LCG/UFRJ. All rights reserved.

Construtor de CópiaConstrutor de Cópia

• O construtor de cópia é chamado sempre que o objeto for passado ou retornado por valor.

• Se nenhum for declarado será criado um default, que aplicará o construtor de cópia correspondente a cada dado da classe.

• Se a declaração for privada, o construtor de cópia será desativado (não poderá ser invocado).

• Ou escreva um construtor de cópia decente ou então desative-o.

Page 20: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

20

2002 LCG/UFRJ. All rights reserved.

memoryCell ( const memoryCell& m ) {*this = m;

}

Uso:memoryCell m1 ( 4 );memoryCell m2 ( m1 );

Exemplo de Exemplo de Construtor de Construtor de

CópiaCópia

Operador de

atribuição

Construtor de Cópia

Page 21: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

21 2002 LCG/UFRJ. All rights reserved.

Operador de AtribuiçãoOperador de Atribuição

• É usado para copiar objetos do mesmo tipo.▪ O operador de cópia cria um novo objeto, mas o

operador “=“ age sobre um objeto já existente.• Operadores de atribuição retornam, em geral,

referências constantes. Retorno por valor não é uma boa idéia ...

• Retornar uma referência não constante torna (A = B) = C válido, mas sem sentido.▪ O resultado é atribuir C à referência A, sem

nunca ter atribuído à B.• Se não for definido haverá uma cópia membro

a membro dos dados da classe por default.

Page 22: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

22

2002 LCG/UFRJ. All rights reserved.

Exemplo de Exemplo de Operador =Operador =

const memoryCell& memoryCell::operator = ( const memoryCell& m ) {

this->cell_value = m.cell_value;return *this;

}

Uso:memoryCell m1 ( 4 );memoryCell m2 = m1;

Referência para este

objeto

Operador de

atribuição

Page 23: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

23 2002 LCG/UFRJ. All rights reserved.

Iniciação X ConstrutorIniciação X Construtor

memoryCell ( int value = 0 ) : cell_value ( value ) { }

• A seqüência depois de “:” é a lista de iniciação.• Os membros são iniciados na ordem em que são

declarados e não na ordem da lista.• O ideal é iniciar cada membro da classe pelo

seu próprio construtor.• É preferível iniciar os membros da classe

usando listas de iniciação ao invés de atribuir no construtor.▪ Cada membro não especificado na lista é iniciado

pelo seu construtor vazio. Só depois é que as atribuições são feitas (trabalho dobrado).

▪ Se a iniciação não for simples, só aí usa-se o corpo do construtor.

Page 24: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

24 2002 LCG/UFRJ. All rights reserved.

Sobreposição de OperadoresSobreposição de Operadores

• Em C++ todos os operadores podem ser sobrepostos, a exceção de: “.”, “.*”, “?” e “sizeof”.▪Precedência e aridade não são

alteradas.• Um operador binário retorna, em geral,

um objeto por valor, porque o resultado é armazenado em um temporário.▪Também pode ser implementado

invocando o operador de atribuição.

Page 25: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

25

2002 LCG/UFRJ. All rights reserved.

Exemplo de Exemplo de SobreposiçãoSobreposição

const memoryCell& memoryCell::operator += ( const memoryCell& m ) {

this->cell_value += m.cell_value;return *this;

}

memoryCell memoryCell::operator + ( const memoryCell& m ) const {

memoryCell temp ( *this );temp += m;return temp;

}

Referência para

este objeto

Adiciona o

segundo operando

Retorna temp por

valor

Page 26: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

26 2002 LCG/UFRJ. All rights reserved.

TemplatesTemplates• Templates servem para escrever rotinas que

funcionam para tipos arbitrários.• O mecanismo baseado em typedef permite

criar rotinas genéricas. ▪ Mas não é suficiente se queremos rotinas que

funcionem com dois tipos diferentes.• Uma template não é uma função comum, mas

sim um padrão para criar funções.• Quando uma template é instanciada com um

tipo particular, uma nova função é criada.• A template é expandida (como uma macro)

para prover uma função real. ▪ O compilador gera código a partir da template

para cada combinação diferente de parâmetros.

Page 27: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

27 2002 LCG/UFRJ. All rights reserved.

Exemplo de Função Exemplo de Função TemplateTemplate

template <class Etype>inline const Etype& Max ( const Etype& a,

const Etype& b ) {return a > b ? a : b;

}

• Etype define o tipo do parâmetro da template.• O código da template pode ser substituído

como uma macro, caso se use a opção inline.• Deve-se retornar uma referência, pois não se

sabe de antemão o tamanho do dado retornado.

• O operador “>”deve estar definido no tipo Etype.

Page 28: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

28 2002 LCG/UFRJ. All rights reserved.

Classes Classes TemplateTemplate

• A sintaxe é similar ao de uma função template.

• Não há sentido em gerar uma biblioteca de templates.▪Lembre-se que o compilador não sabe

que tipos serão necessários. Logo, não gera código algum.

▪Ou todo o código da template está junto com a interface, ou a template deve ser instanciada de antemão para cada tipo a ser usado na aplicação.

Page 29: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

29

2002 LCG/UFRJ. All rights reserved.

TemplateTemplate memoryCellmemoryCell

// memoryCell.h#ifndef __MEMORY_CELL__#define __MEMORY_CELL__/** * A very simple interface for a template class. */template <class Etype> class memoryCell { public:

/** empty construtor. * Sets the content of this cell to value. */ memoryCell ( const Etype& value = Etype() ) {

cell_value = value; }

/** the correct way of returning the content of this cell. * @return the content of this cell. */

const Etype& read ( ) const { return cell_value; }

/** sets a new value for this cell. * @param x new value. */

void write ( const Etype& x ) { cell_value = x; }

private:

/// holds the content of this cell. Etype cell_value;

};#endif

Especificação template antes da classe

Referência

constante

Pode assumir qualquer tipo

Page 30: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

30

2002 LCG/UFRJ. All rights reserved.

Uso da Uso da TemplateTemplate

memoryCellmemoryCell

main ( ) {memoryCell <int> m;

m.write ( 5 ); cout << “Conteúdo da célula é: “

#if 1 << m.read ( )

#else << m.cell_value

#endif << ‘\n’;

return 0;}

Instancia a

template com int

Page 31: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

31 2002 LCG/UFRJ. All rights reserved.

HerançaHerança

• Talvez o principal objetivo de programação orientada a objeto seja a reutilização de código.

• Templates são apropriadas quando a funcionalidade básica do código é independente de tipo.

• Herança serve para estender a funcionalidade de um objeto.▪Criam-se novos tipos com propriedades

restritas ou estendidas do tipo original.

Page 32: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

32 2002 LCG/UFRJ. All rights reserved.

PolimorfismoPolimorfismo

• Polimorfismo permite que um objeto possa armazenar vários tipos diferentes de objetos.

• Quando uma operação for aplicada a um objeto polimorfo será selecionada automaticamente aquela adequada ao tipo armazenado.

• Sobreposição (overload) de funções e operadores é um exemplo de polimorfismo.▪Neste caso, a seleção da função é feita

em tempo de compilação, o que limita o comportamento polimorfo.

Page 33: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

33 2002 LCG/UFRJ. All rights reserved.

ReutilizaçãoReutilização

• Em C++ é possível postergar a seleção da função até que o programa esteja sendo executado.▪ O mecanismo básico usa herança.

• Freqüentemente, no projeto de uma nova classe, descobre-se que há uma classe similar escrita anteriormente.▪ Reutilização de código sugere que não se

comece do zero, mas que se escreva uma nova classe baseada na classe existente.

• Em C++ o mecanismo é criar uma classe abstrata polimorfa que possa armazenar os objetos das classes similares.

Page 34: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

34 2002 LCG/UFRJ. All rights reserved.

ExemplosExemplos

• Classe Vetor: Vetores limitados.• Classe Data: Calendários diversos

(Gregoriano, Hebreu, Chinês).• Impostos: vários tipos de contribuintes

(solteiro, casado, separado, cabeça de casal).

• Formas: (círculos, quadrados, triângulos).

Page 35: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

35 2002 LCG/UFRJ. All rights reserved.

Três OpçõesTrês Opções• Definir classes completamente independentes.

▪ Implica em escrever vários pedaços de código idênticos.▪ Aumenta a chance de erro e cada mudança deve ser

replicada.• Usar uma única classe e controlar as funções por if / else e

switches.▪ Manutenção é difícil, pois cada alteração requer

recompilar todo o código.▪ Extensão das classes por um programador não é

possível a menos que todo o fonte esteja disponível.▪ If / else gasta tempo de execução, mesmo que o

resultado seja conhecido em tempo de compilação.▪ Não há segurança de tipos, pois se toda forma está

contida em uma única classe, pode-se atribuir um círculo a um triângulo.

Page 36: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

36 2002 LCG/UFRJ. All rights reserved.

DerivaçãoDerivação

• Derivar classes a partir de uma classe base (herança).▪Uma classe derivada herda todas as

propriedades da classe base.▪Cada classe derivada é uma nova classe.

Logo, a classe base não é afetada por mudanças nas classes derivadas.

▪Uma classe derivada é compatível por tipo com a base, mas o contrário é falso.

▪Classes irmãs não são compatíveis por tipo.

Page 37: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

37 2002 LCG/UFRJ. All rights reserved.

AnáliseAnálise• As primeiras duas opções são típicas de

programação procedural. • A terceira opção é aquela que deve ser adotada

em programação orientada a objeto.

class Derivada: public Base {// membros não listados são herdados.public:// construtores e destrutores (em geral

// diferentes da base)// membros da base sobrepostos// novos membros públicosprivate:// dados adicionais (geralmente privados)// funções privadas adicionais// membros da base a serem desativados

};

Page 38: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

38 2002 LCG/UFRJ. All rights reserved.

Uso de Ponteiros com HerançaUso de Ponteiros com Herança

• Ponteiro para classe base▪ classeBase* bPtr = NULL; ▪ classeBase bVar; Objeto do tipo base.▪ bPtr = &bVar; Trivialmente válido.▪ bPtr = &dVar; dVar é do tipo classeDerivada.▪ bPtr->print(); Chama print da classe base.

• Ponteiro para classe derivada▪ classeDerivada* dPtr = NULL;▪ classeDerivada dVar; Objeto do tipo derivado.▪ dPtr = &dVar; Trivialmente válido.▪ dPtr = &bVar; ERRO!!▪ dPtr->print(); Chama print da derivada.

Page 39: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

39 2002 LCG/UFRJ. All rights reserved.

Apontar Ponteiro Derivado para Apontar Ponteiro Derivado para Classe BaseClasse Base

• Gera erro. ▪Classe derivada pode ter métodos e

variáveis que não existem na classe base.

▪Objeto da classe base não é do mesmo tipo do objeto da classe derivada.

Page 40: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

40 2002 LCG/UFRJ. All rights reserved.

Apontar ponteiro Base para Classe Apontar ponteiro Base para Classe DerivadaDerivada

• Mecanismo válido. ▪Mas só podem ser chamados métodos

da classe base.▪Chamada a métodos da classe derivada

gera erro.• Tipo de um ponteiro ou referência

define os métodos que podem ser invocados.

Page 41: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

41 2002 LCG/UFRJ. All rights reserved.

Funções VirtuaisFunções Virtuais

• Objetos (e não os ponteiros) definem os métodos que devem ser invocados.

• Suponha círculo, triângulo e retângulo derivados de uma classe forma.▪Cada um com seu próprio método de

desenho (draw).• Para desenhar qualquer forma, chama-se

draw a partir de um ponteiro para forma.▪O programa determina, em tempo de

execução, qual draw chamar (formas são tratadas de maneira genérica).

Page 42: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

42 2002 LCG/UFRJ. All rights reserved.

Declaração VirtualDeclaração Virtual

• Draw deve ser declarada virtual na classe base.▪Sobreponha-se draw em cada classe

derivada.▪As assinaturas devem ser idênticas.▪Um vez declarada virtual, será virtual

em todas as classes derivadas.▪É boa prática manter a declaração

virtual nas classes derivadas, embora não seja mandatário.

Page 43: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

43 2002 LCG/UFRJ. All rights reserved.

Tipos de HerançaTipos de Herança

• Pública: todos os membros públicos da classe básica permanecem públicos.▪Membros privados permanecem

privados. ▪Relacionamento É-Um (IS-A).

• Privada: mesmo membros públicos são escondidos. ▪Relacionamento Tem-Um (HAS-A).▪É preferível usar composição do que

herança privada.▪É a herança default.

Page 44: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

44 2002 LCG/UFRJ. All rights reserved.

Herança de ConstrutoresHerança de Construtores

• O estado de público ou privado dos construtores, construtor de cópia, e operador de atribuição são herdados.▪Se eles forem herdados, mas não

definidos na classe derivada, os operadores correspondentes são aplicados a cada membro.

Page 45: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

45 2002 LCG/UFRJ. All rights reserved.

BindingBinding Estático e Dinâmico Estático e Dinâmico

• No binding estático a decisão de que função invocar para resolver uma sobreposição é tomada em tempo de compilação.

• No binding dinâmico a decisão é tomada em tempo de execução.

• C++ usa binding estático por default, porque se achava no passado que o overhead seria significativo.

• Para forçar o binding dinâmico o programador deve especificar a função como virtual.

Page 46: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

46 2002 LCG/UFRJ. All rights reserved.

Porque Porque bindingbinding dinâmico? dinâmico?

• Quando se declara um ponteiro para uma classe como argumento de uma função, normalmente o tipo do ponteiro é o da classe base.▪ Assim, pode ser passada qualquer uma das

classes derivadas e o tipo do objeto apontado é determinado em tempo de execução.

▪ Virtualidade é herdada. ▪ Funções redefinidas em classes derivadas

devem ser declaradas virtuais.▪ Uma decisão em tempo de execução só é

necessária quando o objeto for acessado através de ponteiros.

Page 47: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

47 2002 LCG/UFRJ. All rights reserved.

Construtores e Destrutores Construtores e Destrutores Virtuais?Virtuais?

• Construtores nunca são virtuais.• Destrutores devem ser virtuais na classe

base apenas.• O tipo de um construtor sempre pode ser

determinado em tempo de compilação.• O destrutor deve ser virtual para garantir

que o destrutor do objeto real é chamado.▪A classe derivada pode ter membros

adicionais que foram alocados dinamicamente, que só podem ser desalocados pelo destrutor da classe derivada.

Page 48: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

48 2002 LCG/UFRJ. All rights reserved.

CustoCusto

• Polimorfismo tem um custo que impacta na performance.▪STL não usa polimorfismo por questão

de eficiência.• Cada classe com função virtual tem

uma tabela vtable.▪Para cada função virtual, vtable tem um

ponteiro para função apropriada.▪Se a classe derivada tiver a mesma

função virtual da classe base, o ponteiro da vtable aponta para a função na base.

Page 49: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

49 2002 LCG/UFRJ. All rights reserved.

Casting (Casting (compatibilizaçãocompatibilização))

• Downcasting▪Operador dynamic_cast

◦Determina o tipo do objeto em tempo de execução.

◦Retorna 0 se não for o tipo certo (não pode sofrer cast)

NewClass *ptr = dynamic_cast < NewClass *> objectPtr;

▪Pode compatibilizar endereço de objeto do tipo base para ponteiro para classe derivada.

Page 50: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

50 2002 LCG/UFRJ. All rights reserved.

Informação de TipoInformação de Tipo

• Keyword typeid▪Header <typeinfo>▪Uso: typeid(object)

◦Retorna type_info do objeto◦Tem informação sobre o tipo do

operando, incluindo nome.◦typeid(object).name()

Page 51: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

51 2002 LCG/UFRJ. All rights reserved.

Tipos de ClasseTipos de Classe

• Classes abstratas▪ Único propósito: ser uma classe base

(chamada classe base abstrata).▪ Incompleta: possui métodos sem código.

◦ Classes derivadas preenchem “pedaços omitidos“.

▪ Objetos não podem ser instanciados a partir de classes abstratas.◦ No entanto, pode haver ponteiros e referências.

• Classes concretas▪ Podem instanciar objetos.▪ Implementam todas as funções que definem.▪ Provêem detalhes.

Page 52: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

52 2002 LCG/UFRJ. All rights reserved.

Função Virtual Pura e RegularFunção Virtual Pura e Regular• Classes abstratas não são necessárias, mas são

úteis. ▪ Ponteiros para classes base abstratas são úteis no

polimorfismo.• Para criar uma classe abstrata:

▪ Precisa-se de uma ou mais função virtual "pura" ◦ Declare-se função com inicializador 0virtual void draw() const = 0;

▪ Função virtual regular◦ Possui implementações, e sobreposição é opcional.

▪ Função virtual pura◦ Nenhuma implementação, mas deve ser sobreposta.

▪ Classes abstratas podem ter dados e funções concretas.◦ Devem ter uma ou mais funções virtuais pura.

Page 53: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

53 2002 LCG/UFRJ. All rights reserved.

Herdando Interface e Herdando Interface e ImplementaçãoImplementação

0.0 0.0 = 0 = 0

0.0 0.0 "Point" [x,y]

r2 0.0 "Circle" center=[x,y]; radius=r

2r2 +2rh r2h "Cylinder"center=[x,y]; radius=r; height=h

getArea printgetNamegetVolume

Shape

Point

Circle

Cylinder

Page 54: 2002 LCG/UFRJ. All rights reserved. 1 Tópicos em C++ Claudio Esperança Paulo Roma Cavalcanti.

54 2002 LCG/UFRJ. All rights reserved.

Funções de DesenhoFunções de Desenho

• Exemplo clássico em OO: método draw.▪Colocar funções de desenho nas classes,

requer acesso a um pacote gráfico nas classes (OpenGL,PHIGS,GKS,Direct X...).

▪Será que é a forma adequada do ponto de vista de portabilidade?

• Alternativa melhor pode ser passar os objetos para uma classe de desenho.▪Apenas a pessoa que escreve essa classe

precisa conhecer Computação Gráfica.