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.
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).
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.
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.
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.
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
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
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;
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.
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
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 ::.
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.
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
atribuio
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.
21
22
const memoryCell& memoryCell::operator = ( const memoryCell& m ) { this->cell_value = m.cell_value; return *this; Referncia }
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.
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
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
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
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;
}; #endif
2002 LCG/UFRJ.
All rights reserved.
main ( ) { memoryCell <int> m; m.write cout << #if 1 << #else << #endif <<
30
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).
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.
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
39
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.
42
Tipos de Herana
Pblica: todos os membros pblicos da classe bsica permanecem pblicos.
Membros privados permanecem privados. Relacionamento -Um (IS-A).
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.
44
46
Custo
Polimorfismo tem um custo que impacta na performance.
STL no usa polimorfismo por questo de eficincia.
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.
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()
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.
Classes concretas
Podem instanciar objetos. Implementam todas as funes que definem. Provem detalhes.
2002 LCG/UFRJ. All rights reserved. 51
Shape
Point
0.0
0.0
"Point"
[x,y]
Circle
pr2
0.0
"Circle"
center=[x,y]; radius=r
Cylinder
2pr2 +2prh
pr2h
"Cylinder"
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