Anda di halaman 1dari 54

Tpicos em C++

Claudio Esperana Paulo Roma Cavalcanti

2002 LCG/UFRJ. All rights reserved.

Classes e Objetos
C++ mais do que C com uns poucos sinos e apitos adicionais. O mecanismo bsico para atingir programao orientada a objeto em C++ o conceito de classe.
Fornece formas de encapsulamento e proteo de informao. Permite reutilizao de cdigo.

2002 LCG/UFRJ. All rights reserved.

O que OO?
Programao 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 operaes que podem acessar ou manipular esse estado. Tipos definidos pelo usurio devem se comportar da mesma maneira de tipos prdefinidos (fornecidos pelo compilador).

2002 LCG/UFRJ. All rights reserved.

Tipos de Dados
Um tipo bsico de dados de uma linguagem, como inteiro, real, ou caractere, fornece certas coisas:
Podem-se declarar novos objetos, com ou sem iniciao. Pode-se copiar ou testar quanto igualdade. Pode-se executar a entrada e a sada de dados com esses objetos.

2002 LCG/UFRJ. All rights reserved.

Objetos
Um objeto uma unidade atmica.
No pode ser dissecado por um programador.

Proteo de informao torna os detalhes de implementao inacessveis. Encapsulamento o agrupamento de dados, e operaes que se aplicam a eles, para formar um agregado.
Mas escondendo a os detalhes de implementao.

Uma classe o mesmo que uma estrutura, mas com os membros protegidos por default.
2002 LCG/UFRJ. All rights reserved. 5

Encapsulamento
O princpio de atomicidade conhecido por encapsulamento.
O usurio no tem acesso direto s partes de um objeto ou a sua implementao. O acesso feito indiretamente, atravs de funes fornecidas com o objeto.

uma forma de imitar a vida real.


Aparelhos eletrnicos possuem o seguinte aviso: No abra no h partes consertveis por um usurio. Pessoas sem treinamento que tentam consertar equipamentos com esses avisos acabam quebrando mais do que consertando.
2002 LCG/UFRJ. All rights reserved. 6

Reutilizao de Cdigo
A idia usar os mesmos componentes sempre que possvel. Quando o mesmo objeto a soluo fica fcil.
O difcil quando se necessita de um objeto ligeiramente diferente.

C++ fornece diversos mecanismos para isso.


Se a implementao for idntica exceto pelo tipo bsico do objeto, pode-se usar uma template. Herana o mecanismo que permite estender a funcionalidade de um objeto.
2002 LCG/UFRJ. All rights reserved. 7

Classes
Classes so usadas para encapsular informao. J que as funes que manipulam o estado do objeto so membros da classe, elas so acessadas pelo operador ., como em uma estrutura de C. Quando se chama uma funo de uma classe, na realidade se est passando uma mensagem para o objeto. A diferena bsica entre OO de C++ e o velho C puramente filosfica: em C++ o objeto tem o papel principal.
2002 LCG/UFRJ. All rights reserved. 8

Para No Esquecer Jamais


Se voc deseja usar OO, acostume-se a esconder todos os dados das classes.
C++ no uma linguagem para preguiosos.

Para isto existe uma seo de dados privados.


O compilador se esforar ao mximo para mant-los inacessveis ao mundo exterior.

Toda classe possui um construtor e um destrutor, que dizem como uma instncia do objeto deve ser iniciada e destruda.
Procure escrev-los sempre. Evite defaults.
2002 LCG/UFRJ. All rights reserved. 9

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

Construtor

10

Exemplo Bobo

value est protegido

2002 LCG/UFRJ.
All rights reserved.

main ( ) { memoryCell m; m.write ( 5 ); cout << Contedo da #if 1 << m.read ( ) #else << m.value #endif << \n; return 0; }

Instancia a classe Armazena clula : um valor Maneira correta Erro!!! value privado!!!

11

Uso da Classe

Diretiva de prprocessamento

2002 LCG/UFRJ.
All rights reserved.

Interface
A interface descreve o que pode ser feito com o objeto.
Necessita de uma boa conveno de nomes. Exemplo: primeira letra de nome de classe ou funo minscula, demais palavras do nome com primeira letra maiscula (sem _). memoryCell. Dados: ponteiros com prefixo ptr e pode usar _. Constantes e tipos enumerveis em caixa alta:
GL_FLOAT, GLUT_DOUBLE;

Prefixo com o nome do pacote.


glLoadIdentity(), glVertex3f.
2002 LCG/UFRJ. All rights reserved. 12

Documentao
fundamental uma documentao mnima em todo o arquivo de um sistema. Existem ferramentas muito boas de domnio pblico, como o Doxygen.
Basta colocar diretivas na forma de comentrios na prpria interface. melhor acrescentar as diretivas durante a confeco da interface para no ter de voltar depois de m vontade.

2002 LCG/UFRJ. All rights reserved.

13

// memoryCell.h // evita incluir a interface de novo se ela j foi // includa 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. No faz nada. ~memoryCell ( ) { }

14

Interface memoryCell

2002 LCG/UFRJ.
All rights reserved.

15 /** the correct way of returning the content of this cell. * @return the content of this cell. */ No altera int read ( ) const; /** sets a new value for this cell. * @param x new value. */ void write ( int x ); private: /// holds the content of this int cell_value; }; #endif

dados desta classe Altera dados desta cell. classe

Interface memoryCell

2002 LCG/UFRJ.
All rights reserved.

Implementao
A implementao contm os detalhes de como a interface foi codificada, de forma a atender as especificaes do projeto. As declaraes dos nomes das funes ficam na declarao da classe e as implementaes so definidas depois, normalmente num arquivo separado (.C, .cpp, ou .cc).
Usam a sintaxe de funo mais o nome da classe e o operador de escopo ::.

2002 LCG/UFRJ. All rights reserved.

16

// memoryCell.C

17

#include memoryCell.h

Construtor
Implementao memoryCell

memoryCell::memoryCell ( int value ) { this->cell_value = value; Membro } int memoryCell::read ( ) const { desta classe return this->cell_value; getter } void memoryCell::write ( int x ) { this->cell_value = x; setter }

2002 LCG/UFRJ.
All rights reserved.

Construtores e Destrutores
O construtor diz como o objeto declarado e iniciado.
Se a iniciao no casar com nenhum construtor, o compilador reclamar.

O destrutor diz como o objeto ser destrudo quando sair de escopo.


No mnimo deve liberar a memria que foi alocada por chamadas newno construtor. Se nenhum destrutor for declarado ser gerado um default, que aplicar o destrutor correspondente a cada dado da classe.
2002 LCG/UFRJ. All rights reserved. 18

Construtor de Cpia
O construtor de cpia chamado sempre que o objeto for passado ou retornado por valor. Se nenhum for declarado ser criado um default, que aplicar o construtor de cpia correspondente a cada dado da classe. Se a declarao for privada, o construtor de cpia ser desativado (no poder ser invocado). Ou escreva um construtor de cpia decente ou ento desative-o.
2002 LCG/UFRJ. All rights reserved. 19

20

memoryCell ( const memoryCell& m ) { *this = m; Operador de }

atribuio

Exemplo de Construtor de Cpia

Construtor de Cpia
Uso: memoryCell m1 ( 4 ); memoryCell m2 ( m1 );
2002 LCG/UFRJ.
All rights reserved.

Operador de Atribuio
usado para copiar objetos do mesmo tipo.
O operador de cpia cria um novo objeto, mas o operador = age sobre um objeto j existente.

Operadores de atribuio retornam, em geral, referncias constantes. Retorno por valor no uma boa idia ... Retornar uma referncia no constante torna (A = B) = C vlido, mas sem sentido.
O resultado atribuir C referncia A, sem nunca ter atribudo B.

Se no for definido haver uma cpia membro a membro dos dados da classe por default.

2002 LCG/UFRJ. All rights reserved.

21

22

const memoryCell& memoryCell::operator = ( const memoryCell& m ) { this->cell_value = m.cell_value; return *this; Referncia }

para este objeto

Exemplo de Operador =

Operador de atribuio
Uso: memoryCell m1 ( 4 ); memoryCell m2 = m1;
2002 LCG/UFRJ.
All rights reserved.

Iniciao X Construtor
memoryCell ( int value = 0 ) : cell_value ( value ) { }

A seqncia depois de : a lista de iniciao. Os membros so iniciados na ordem em que so declarados e no na ordem da lista. O ideal iniciar cada membro da classe pelo seu prprio construtor. prefervel iniciar os membros da classe usando listas de iniciao ao invs de atribuir no construtor.
Cada membro no especificado na lista iniciado pelo seu construtor vazio. S depois que as atribuies so feitas (trabalho dobrado). Se a iniciao no for simples, s a usa-se o corpo do construtor.
2002 LCG/UFRJ. All rights reserved. 23

Sobreposio de Operadores
Em C++ todos os operadores podem ser sobrepostos, a exceo de: ., .*, ? e sizeof.
Precedncia e aridade no so alteradas.

Um operador binrio retorna, em geral, um objeto por valor, porque o resultado armazenado em um temporrio.
Tambm pode ser implementado invocando o operador de atribuio.

2002 LCG/UFRJ. All rights reserved.

24

25

const memoryCell& memoryCell::operator += ( const memoryCell& m ) { this->cell_value += m.cell_value; return *this; Referncia } para este

memoryCell memoryCell::operator + ( const memoryCell& m ) const { memoryCell temp ( *this ); Adiciona o temp += m; segundo return temp; Retorna operando } temp por

objeto

Exemplo de Sobreposio

valor

2002 LCG/UFRJ.
All rights reserved.

Templates
Templates servem para escrever rotinas que funcionam para tipos arbitrrios. O mecanismo baseado em typedef permite criar rotinas genricas.
Mas no suficiente se queremos rotinas que funcionem com dois tipos diferentes.

Uma template no uma funo comum, mas sim um padro para criar funes. Quando uma template instanciada com um tipo particular, uma nova funo criada. A template expandida (como uma macro) para prover uma funo real.
O compilador gera cdigo a partir da template para cada combinao diferente de parmetros.
2002 LCG/UFRJ. All rights reserved. 26

Exemplo de Funo Template


template <class Etype> inline const Etype& Max ( const Etype& a, const Etype& b ) { return a > b ? a : b; }

Etype define o tipo do parmetro da template. O cdigo da template pode ser substitudo como uma macro, caso se use a opo inline. Deve-se retornar uma referncia, pois no se sabe de antemo o tamanho do dado retornado. O operador >deve estar definido no tipo Etype.
27

2002 LCG/UFRJ. All rights reserved.

Classes Template
A sintaxe similar ao de uma funo template. No h sentido em gerar uma biblioteca de templates.
Lembre-se que o compilador no sabe que tipos sero necessrios. Logo, no gera cdigo algum. Ou todo o cdigo da template est junto com a interface, ou a template deve ser instanciada de antemo para cada tipo a ser usado na aplicao.
2002 LCG/UFRJ. All rights reserved. 28

// 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; }

29

Especificao template antes da classe

Template memoryCell

/** 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 * @param x new value. */ void write ( const Etype& x ) { cell_value = x; } private: /// holds the content of this cell. Etype cell_value;

Referncia this cell. constante

}; #endif

Pode assumir qualquer tipo

2002 LCG/UFRJ.
All rights reserved.

main ( ) { memoryCell <int> m; m.write cout << #if 1 << #else << #endif <<

( 5 ); Contedo da clula : m.read ( ) m.cell_value \n;

Instancia a template com int

30

Uso da Template memoryCell

return 0;

2002 LCG/UFRJ.
All rights reserved.

Herana
Talvez o principal objetivo de programao orientada a objeto seja a reutilizao de cdigo. Templates so apropriadas quando a funcionalidade bsica do cdigo independente de tipo. Herana serve para estender a funcionalidade de um objeto.
Criam-se novos tipos com propriedades restritas ou estendidas do tipo original.
2002 LCG/UFRJ. All rights reserved. 31

Polimorfismo
Polimorfismo permite que um objeto possa armazenar vrios tipos diferentes de objetos. Quando uma operao for aplicada a um objeto polimorfo ser selecionada automaticamente aquela adequada ao tipo armazenado. Sobreposio (overload) de funes e operadores um exemplo de polimorfismo.
Neste caso, a seleo da funo feita em tempo de compilao, o que limita o comportamento polimorfo.
2002 LCG/UFRJ. All rights reserved. 32

Reutilizao
Em C++ possvel postergar a seleo da funo at que o programa esteja sendo executado.
O mecanismo bsico usa herana.

Freqentemente, no projeto de uma nova classe, descobre-se que h uma classe similar escrita anteriormente.
Reutilizao de cdigo sugere que no 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.
2002 LCG/UFRJ. All rights reserved. 33

Exemplos
Classe Vetor: Vetores limitados. Classe Data: Calendrios diversos (Gregoriano, Hebreu, Chins). Impostos: vrios tipos de contribuintes (solteiro, casado, separado, cabea de casal). Formas: (crculos, quadrados, tringulos).

2002 LCG/UFRJ. All rights reserved.

34

Trs Opes
Definir classes completamente independentes. Implica em escrever vrios pedaos de cdigo idnticos. Aumenta a chance de erro e cada mudana deve ser replicada. Usar uma nica classe e controlar as funes por if / else e switches. Manuteno difcil, pois cada alterao requer recompilar todo o cdigo. Extenso das classes por um programador no possvel a menos que todo o fonte esteja disponvel. If / else gasta tempo de execuo, mesmo que o resultado seja conhecido em tempo de compilao. No h segurana de tipos, pois se toda forma est contida em uma nica classe, pode-se atribuir um crculo a um tringulo.

2002 LCG/UFRJ. All rights reserved.

35

Derivao
Derivar classes a partir de uma classe base (herana).
Uma classe derivada herda todas as propriedades da classe base. Cada classe derivada uma nova classe. Logo, a classe base no afetada por mudanas nas classes derivadas. Uma classe derivada compatvel por tipo com a base, mas o contrrio falso. Classes irms no so compatveis por tipo.
2002 LCG/UFRJ. All rights reserved. 36

Anlise
As primeiras duas opes so tpicas de programao procedural. A terceira opo aquela que deve ser adotada em programao orientada a objeto.
class Derivada: public Base { // membros no listados so herdados. public: // construtores e destrutores (em geral // diferentes da base) // membros da base sobrepostos // novos membros pblicos private: // dados adicionais (geralmente privados) // funes privadas adicionais // membros da base a serem desativados };
2002 LCG/UFRJ. All rights reserved. 37

Uso de Ponteiros com Herana


Ponteiro para classe base
classeBase* bPtr = NULL; classeBase bVar; Objeto do tipo base. bPtr = &bVar; Trivialmente vlido. bPtr = &dVar; dVar do tipo classeDerivada. bPtr->print(); Chama print da classe base. classeDerivada* dPtr = NULL; classeDerivada dVar; Objeto do tipo derivado. dPtr = &dVar; Trivialmente vlido. dPtr = &bVar; ERRO!! dPtr->print(); Chama print da derivada.
2002 LCG/UFRJ. All rights reserved. 38

Ponteiro para classe derivada

Apontar Ponteiro Derivado para Classe Base


Gera erro.
Classe derivada pode ter mtodos e variveis que no existem na classe base. Objeto da classe base no do mesmo tipo do objeto da classe derivada.

2002 LCG/UFRJ. All rights reserved.

39

Apontar ponteiro Base para Classe Derivada


Mecanismo vlido.
Mas s podem ser chamados mtodos da classe base. Chamada a mtodos da classe derivada gera erro.

Tipo de um ponteiro ou referncia define os mtodos que podem ser invocados.

2002 LCG/UFRJ. All rights reserved.

40

Funes Virtuais
Objetos (e no os ponteiros) definem os mtodos que devem ser invocados. Suponha crculo, tringulo e retngulo derivados de uma classe forma.
Cada um com seu prprio mtodo de desenho (draw).

Para desenhar qualquer forma, chama-se draw a partir de um ponteiro para forma.
O programa determina, em tempo de execuo, qual draw chamar (formas so tratadas de maneira genrica).
2002 LCG/UFRJ. All rights reserved. 41

Declarao Virtual
Draw deve ser declarada virtual na classe base.
Sobreponha-se draw em cada classe derivada. As assinaturas devem ser idnticas. Um vez declarada virtual, ser virtual em todas as classes derivadas. boa prtica manter a declarao virtual nas classes derivadas, embora no seja mandatrio.

2002 LCG/UFRJ. All rights reserved.

42

Tipos de Herana
Pblica: todos os membros pblicos da classe bsica permanecem pblicos.
Membros privados permanecem privados. Relacionamento -Um (IS-A).

Privada: mesmo membros pblicos so escondidos.


Relacionamento Tem-Um (HAS-A). prefervel usar composio do que herana privada. a herana default.
2002 LCG/UFRJ. All rights reserved. 43

Herana de Construtores
O estado de pblico ou privado dos construtores, construtor de cpia, e operador de atribuio so herdados.
Se eles forem herdados, mas no definidos na classe derivada, os operadores correspondentes so aplicados a cada membro.

2002 LCG/UFRJ. All rights reserved.

44

Binding Esttico e Dinmico


No binding esttico a deciso de que funo invocar para resolver uma sobreposio tomada em tempo de compilao. No binding dinmico a deciso tomada em tempo de execuo. C++ usa binding esttico por default, porque se achava no passado que o overhead seria significativo. Para forar o binding dinmico o programador deve especificar a funo como virtual.
2002 LCG/UFRJ. All rights reserved. 45

Porque binding dinmico?


Quando se declara um ponteiro para uma classe como argumento de uma funo, 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 execuo. Virtualidade herdada. Funes redefinidas em classes derivadas devem ser declaradas virtuais. Uma deciso em tempo de execuo s necessria quando o objeto for acessado atravs de ponteiros.

2002 LCG/UFRJ. All rights reserved.

46

Construtores e Destrutores Virtuais?


Construtores nunca so virtuais. Destrutores devem ser virtuais na classe base apenas. O tipo de um construtor sempre pode ser determinado em tempo de compilao. 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.
2002 LCG/UFRJ. All rights reserved. 47

Custo
Polimorfismo tem um custo que impacta na performance.
STL no usa polimorfismo por questo de eficincia.

Cada classe com funo virtual tem uma tabela vtable.


Para cada funo virtual, vtable tem um ponteiro para funo apropriada. Se a classe derivada tiver a mesma funo virtual da classe base, o ponteiro da vtable aponta para a funo na base.
2002 LCG/UFRJ. All rights reserved. 48

Casting (compatibilizao)
Downcasting
Operador dynamic_cast
Determina o tipo do objeto em tempo de execuo. Retorna 0 se no for o tipo certo (no pode sofrer cast)
NewClass *ptr = dynamic_cast < NewClass *> objectPtr;

Pode compatibilizar endereo de objeto do tipo base para ponteiro para classe derivada.

2002 LCG/UFRJ. All rights reserved.

49

Informao de Tipo
Keyword typeid
Header <typeinfo> Uso: typeid(object)
Retorna type_info do objeto Tem informao sobre o tipo do operando, incluindo nome. typeid(object).name()

2002 LCG/UFRJ. All rights reserved.

50

Tipos de Classe
Classes abstratas
nico propsito: ser uma classe base (chamada classe base abstrata). Incompleta: possui mtodos sem cdigo.
Classes derivadas preenchem pedaos omitidos.

Objetos no podem ser instanciados a partir de classes abstratas.


No entanto, pode haver ponteiros e referncias.

Classes concretas
Podem instanciar objetos. Implementam todas as funes que definem. Provem detalhes.
2002 LCG/UFRJ. All rights reserved. 51

Funo Virtual Pura e Regular


Classes abstratas no so necessrias, mas so teis.
Ponteiros para classes base abstratas so teis no polimorfismo.

Para criar uma classe abstrata:


Precisa-se de uma ou mais funo virtual "pura"
Declare-se funo com inicializador 0 virtual void draw() const = 0;

Funo virtual regular


Possui implementaes, e sobreposio opcional.

Funo virtual pura


Nenhuma implementao, mas deve ser sobreposta.

Classes abstratas podem ter dados e funes concretas.


Devem ter uma ou mais funes virtuais pura.
2002 LCG/UFRJ. All rights reserved. 52

Herdando Interface e Implementao


getArea 0.0 getVolume 0.0 getName = 0 print = 0

Shape

Point

0.0

0.0

"Point"

[x,y]

Circle

pr2

0.0

"Circle"

center=[x,y]; radius=r

Cylinder

2pr2 +2prh

pr2h

"Cylinder"

center=[x,y]; radius=r; height=h

2002 LCG/UFRJ. All rights reserved.

53

Funes de Desenho
Exemplo clssico em OO: mtodo draw.
Colocar funes de desenho nas classes, requer acesso a um pacote grfico 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 Computao Grfica.
2002 LCG/UFRJ. All rights reserved. 54