Programação Orientada a Objetos -...
Transcript of Programação Orientada a Objetos -...
Programação Orientada a Objetos
Renato Dourado MaiaUniversidade Estadual de Montes Claros
Engenharia de Sistemas
OUTROS MECANISMOS
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 2/36
Unidade V
• Unidade IV – Outros Mecanismos:– Classes parametrizadas.– A biblioteca padrão.– Exceções.– Identificação de tipo em tempo de execução.
• Hoje trabalharemos o tópico Classes Parametrizadas.– Os demais tópicos serão estudados por vocês durante o
desenvolvimento do Trabalho Prático IV.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 3/36
Templates
• Stroustrup inicialmente chamou os templates de ti-pos parametrizados: – Uma classe ou uma função template serve como uma “re-
ceita” para a geração automática de classes e funções, com base na escolha de um tipo pelo usuário.
• As classes e algoritmos presentes na biblioteca pa-drão (vector<T>, list<T>, sort, find, etc ) são exem-plos de classes e funções template.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 4/36
Exemplo – Uma Pilha (Simples) de Inteiros
class IntStack{ int* stack ; int top, ssize; public: IntStack(int size):top(0),ssize(size){stack = new int[size];}; ~IntStack() { delete[] stack; } void push(int i) { if(top >= ssize) { cout << “Too many push()es” ; exit(1);} stack[top++] = i; } int pop() { if (top <= 0) { cout << “Too many pop()s”; exit(1); } return stack[--top]; }};
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 5/36
Pergunta Interessante
E se o desejo for trabalhar com uma pilha de objetos de
qualquer tipo?
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 6/36
Solução 1 (Horrorosa!)
• Copiar o código da pilha de inteiros e realizar os a-justes necessários para o novo tipo: uma pilha de a-viões.
• Desvantagens:– Cansativo.– Confuso.– Propenso a erros.– Deselegante.
ECA!
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 7/36
Solução 2 (Não Muito Bonita...)
• Uma classe da biblioteca padrão é a base para as de-mais classes, não existindo mais do que uma árvore hierárquica.– Utiliza-se a herança da classe base genérica:
✔ Classe base genérica: Object.✔ As demais classes devem ser criadas a partir da classe base Object.
Assim, seus objetos são armazenados no container de ponteiros para Object.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 8/36
Solução 3 – Templates
• Em C++, tentou-se inicialmente implementar a solu-ção apresentada no slide anterior:– A utilização do mecanismo era complicada e confusa, es-
pecialmente porque todas as classes deveriam ser deriva-das de uma única classe: Object!
– Em muitas situações era necessário introduzir herança múltipla...
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 9/36
Solução 3 – Templates
• Inicialmente, Stroustrup propôs criar as classes con-tainers como sendo grandes macros com argumen-to. Assim, ao se criar um container para um objeto, fazia-se uma dupla chamada da macro.– Infelizmente, essa solução era mais confusa do que as so-
luções existentes até então...
• Finalmente, Stroustrup modificou essa macro origi-nal, simplificando-a e movendo-a do domínio do pré-processador para dentro do compilador. Esse novo dispositivo ele denominou de Templates.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/36
Solução 3 – Templates
• Os Templates C++ permitem a execução de um mol-de genérico Stack<T> com parâmetro T de qualquer tipo, podendo esse tipo ser primitivo da linguagem ou definido pelo próprio usuário.
• Os Templates C++ fornecem uma maneira reuso do código fonte, ao contrário da herança e da compo-sição, que fornecem uma maneira de reuso do códi-go objeto.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 11/36
Solução 3 – Templates
• Template é a palavra chave para o compilador identi-ficar que a classe ou função manipulará um tipo não especificado:– O mecanismo pode ser implementado na forma de classes
template ou de funções template.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 12/36
Funções Template
• Sintaxe para a definição:
– Exemplo:
template <class Tipo1 [,..., class Tipo2]>protótipo_função_template(){ //código da função template }
template <class T> T soma(const T& p1, const T& p2){ return(p1+p2);}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 13/36
Funções Template
• Utilização:
int i = 1 , j = 2;double f = 3., g = 4.;Matriz A(20,20), B(20,20);// gera int soma(const int& , const int&)int k = soma(i,j); // gera double soma(const double& , const double&) double h = soma(f,g); // gera Matriz soma(const Matriz& , const Matriz&)// (se existir Matriz::operator+)Matriz C = soma(A,B);
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 14/36
Funções Template
• O código do slide anterior mostra claramente uma ca-racterística das funções template: elas só podem ser instanciadas (ter seu tipo genérico T substituído por um “tipo de verdade”) caso o “tipo de verdade” sa-tisfaça alguns pré-requisitos...– No caso específico da função soma, quais seriam os pré-
requisitos?
template <class T> T soma(const T& p1, const T& p2){ return(p1+p2); }
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 15/36
Funções Template
• No caso específico da função soma, quais seriam os pré-requisitos?
• O tipo T:– Tem que ter implementado o operator+!– Deve possuir também um construtor de cópia (criado pelo
programador ou sintetizado pelo compilador) para permi-tir o retorno por cópia.
template <class T> T soma(const T& p1, const T& p2){ return(p1+p2);}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 16/36
Funções Template
• Quando uma função template é chamada, os tipos dos argumentos da função determinam qual versão do template será utilizada, isto é, os parâmetros do template são deduzidos a partir dos argumentos da função.
• Cada vez que o compilador encontrar uma chamada de função template ainda não realizada para aqueles tipos, ele definirá um novo código (as várias funções terão endereços e códigos diferentes): esse processo é chamado de instanciação da função template.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 17/36
Funções Template – Exemplo
template< class T > void printArray( const T *array, const int count ){ for ( int i = 0; i < count; i++ ) cout << array[ i ] << " "; cout << endl; }int main() { const int aCount = 5, bCount = 7, cCount = 6; int a[ aCount ] = { 1, 2, 3, 4, 5 }; double b[ bCount ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; char c[ cCount ] = "HELLO"; // 6th position for null printArray( a, aCount ); // integer template function printArray( b, bCount ); // double template function printArray( c, cCount ); // character template function return 0; }
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 18/36
Templates – Argumentos Explícitos
• Em algumas situações, não é possível para o compi-lador deduzir qual é o tipo de argumentos do tem-plate.
• Solução: indicar explicitamente a instância desejada:
template <class T> T max (T t1, T t2) { return (t1 > t2 ? t1 : t2);}unsigned int ui = 10;int ia = 1;// Erro! Deve instanciar max<unsigned int> ou max<int> ?max(ui, ia);
max< unsigned int > (ui, ia);
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 19/36
Templates – Especialização Explícita
• Nem sempre é possível escrever uma única função template que funcione bem para todos os tipos para os quais ela pode ser instanciada.
• Em alguns casos, pode-se tirar vantagem do conhe-cimento específico que se tem sobre algum tipo para escrever uma função mais eficiente do que a instan-ciada pelo template.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 20/36
Templates – Especialização Explícita
• Em outros casos, a função é simplesmente uma fun-ção errada para o tipo:
• Essa função não funciona corretamente para o tipo const char * (string do C)
• Para resolver esse problema, pode-se criar uma es-pecialização explícita para a função para o tipo const char* !
template <class T>T max (T t1, T t2) { return (t1 > t2 ? t1 : t2);}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 21/36
Templates – Especialização Explícita
• Especialização explícita para const char*:
#include <cstring>
typedef const char *PCC;
template<> PCC max< PCC > (PCC s1, PCC s2) {return ( strcmp( s1 , s2) > 0 ? s1 : s2 ) ;
}
int main () { int i = max (10, 5); // chama int max<int> (int, int); // Chama a especialização max<PCC> (PCC, PCC); const char *p = max (“hello”, “world”) ; }
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 22/36
Classes Template – Pilha
template <class T>class Stack{ T* stack ; int top, ssize; public: Stack(int size):top(0),ssize(size){stack = new T[size];}; ~Stack() { delete[] stack; } void push(T i) { if(top >= ssize) { cout << “Too many push()es” ; exit(1);} stack[top++] = i; } T pop() { if (top <= 0) { cout << “Too many pop()s”; exit(1); } return stack[--top]; }};
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 23/36
Classes Template – Array
template<class T> class Array{ private: T* A; int size; public: Array(int tam):size(tam)
{A = new T[tam];} T& operator[](int index)
{ return A[index];}};
int main(){ Array<int> ia(20); Array<float> fa(20); for(int i=0; i<20; i++){ ia[i]=i*i; fa[i]=i*1.414; } for(int j=0; j<20; j++) cout << j << “: “ << ia[j] << “, “ << fa[j] << endl;}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 24/36
Classes Template – Funções não inlinetemplate<class T> class Array{ private: T* A; int size; public: Array(int tam); T &operator[](int index);};// Funções não inlinetemplate<class T> Array<T>:: Array(int tam):size(tam){
A = new T[tam]; }template<class T> T & Array<T>:: operator[](int index)
{return A[index];}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 25/36
Classes Template – Pilha com Constante
template<class T,int sz=100> class Stack { private: T stack[sz]; int top; public: Stack() : top(0){}; void push (const T &i); T pop(); int size() { return top }; T peek() const;};
template<class T, int sz> void Stack<T,sz> :: push(const T&i) { if(top >= sz){ cout<<“Too many push()es”; exit(1); } stack[top++] = i;}
template<class T, int sz> T Stack<T,sz> :: pop(){ if (top <= 0) {cout<<“Too many pop()s”; exit(1); } return stack[--top];}
template<class T, int sz> T Stack<T,sz> :: peek() const { return stack[top-1];}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 26/36
Instanciação das Funções Template
• Uma função membro de uma classe template tam-bém é uma função template;
• A norma C++ exige que essa função membro somen-te seja instanciada quando chamada explicitamente ou quando o seu endereço é utilizado (por meio de um ponteiro para a função): – Uma função membro de uma classe template não é ins-
tanciada automaticamente quando a classe template é instanciada!
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 27/36
Classes Template e Membros Static
• Uma classe template pode declarar membros de da-dos static. – Cada instanciação da classe template vai possuir seu pró-
prio conjunto de membros de dados static.
• Como todo membro static de dados, ele deve ser ini-cializado fora da classe:
template <class T>class Ponto {
T x;T ystatic int npontos;// etc ...
};template <class T> int Ponto<T>::npontos = 0;
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 28/36
Classes Template e Herança
• Os conceitos básicos associados à herança também podem ser utilizados em conjunto com classes tem-plates:– Além de gerar classes, podem ser geradas hierarquias de
classes com templates, sendo que cada hierarquia é para-metrizada.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 29/36
Classes Template e Herança
• Podem-se criar:– Classes template derivadas de classes template.– Classes comuns derivadas de instâncias de classes tem-
plate.– Classes template derivadas de classes comuns.– Classes template derivadas de instâncias de classes tem-
plate.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 30/36
Classes Template e Herança
• Funções virtuais são permitidas na hierarquia, o que permite a utilização de polimorfismo.
• Pode-se ter também classes template abstratas, etc...
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 31/36
Classes Template e Herança
template <class T> class Base { // Classe template T b;};template<class T> class D1 : public Base<T> { // template derivada de template T c;};template <class T> class D2 : public Base <int> { // template derivada de instância T d;};class D3 : public Base<float> { // classe comum derivada de instância int f;};template <class T> class D4 : public D3 { // template derivada de classe comum T g;};
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 32/36
Templates e Header Files
• Existem duas maneiras de organizar o código fonte quando funções e classes templates são utilizadas:– Colocar as declarações e definições das classes em um .h.
✔ Isso pode parecer que viola a regra normal dos arquivos de cabe-çalho, mas definições de templates são especiais, pois o compila-dor necessita efetuar a substituição de código fonte.
– Compiladores “teoricamente” permitem a separação dos arquivos .h e .cpp, mas a palavra chave export deve ser utilizada.
✔ A palavra export significa: “é acessível a partir de outra unidade de compilação”.
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 33/36
Classes Template e Funções Membro Template
• Uma função membro de uma classe template pode ser uma função template parametrizada por um ou-tro tipo:
template<class T, int size > class Array{ private: T A[size]; public: T &operator[](int index) { return A[index];} template <class Iter> void copy(Iter first, Iter last) { for(int i=0; first != last; ++first, ++i)
A[i] = *first; } };
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 34/36
Classes Template e Funções Membro Template
• A função membro template também pode ser defini-da fora da definição da classe:
template<class T, int size > class Array{ private: T A[size]; public: T &operator[](int index) { return A[index];} template <class Iter> void copy(Iter first, Iter last);};template <class T, int size> template <class Iter> void Array< T, int size > :: copy(Iter first, Iter last){ for(int i=0; first != last; ++first, ++i) A[i] = *first;}
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 35/36
Importante
• Esta apresentação é uma adaptação do material ori-ginalmente desenvolvido pelo professor Renato Car-doso Mesquita, do Departamento de Engenharia Elé-trica da Universidade Federal de Minas Gerais.
http://www.cpdee.ufmg.br/~renato
24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 36/36
That's All Folks!