21
Programação de Computadores 350 Template de classe ! Idéia é semelhante ao template de função ! Usando a classe vetor que foi desenvolvida anteriormente: class vetor { int *arranjo; int limite; public: vetor(int=100); int & operator[ ](int n); }; ! Só pode ser usada em situações onde vou manipular vetor de inteiros ! Para poder ser usada para armazenar qualquer tipo " template da classe.

Template de classe - dc.ufscar.br · Programação de Computadores 354 Problemas:! cada retorno de função deve ser examinado no programa" listagem confusa e difícil de ler. Também

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Programação de Computadores 350

Template de classe! Idéia é semelhante ao template de função! Usando a classe vetor que foi desenvolvida anteriormente:

class vetor{ int *arranjo;

int limite;public:

vetor(int=100);int & operator[ ](int n);

};! Só pode ser usada em situações onde vou manipular vetor

de inteiros! Para poder ser usada para armazenar qualquer tipo "

template da classe.

Programação de Computadores 351

#include <iostream.h>#include <stdlib.h>#include <assert.h>template <class T>class vetor{ T *arranjo;

int limite;public:vetor(int=100);int & operator[ ](int n);

};template <class T>vetor<T>::vetor( int n){ limite = n;

arranjo = new T[limite];assert(arranjo!=0);

}

template <class T>T& vetor<T>::operator[ ](int n){ if (n<0 || n>=limite)

{ cout<<“Indice fora dos limites” <<endl;

exit(1);}

return arranjo[n];}// arquivo temp_vet.hNo programa principal quando declaramos um objeto, colocamos qual será o seu tipo.Por exemplo:vetor <int> v1;vetor <float> v2;

Programação de Computadores 352

Exceções! Fornecem uma maneira de manipular erros em tempo de

execução (“run time errors”) gerados por classes! Para qualificar uma exceção, tais erros devem ocorrer

como resultado de alguma ação feita dentro de um programa e o programa deve ser capaz de reconhecer

! Exemplos:! numa classe string definida pelo usuário podemos gerar uma

exceção numa tentativa de iniciar um objeto com uma string muito longa;

! Num programa trabalhando com arquivos, testar se o arquivo foi aberto ou se a escrita foi feita com sucesso e gerar exceções setais fatos não ocorreram ( nos nossos exemplos, terminamos o programa)

! Nem todos os erros em tempo de execução podem ser tratados como exceção, alguns são detectados pelo S.O. e podem terminar a aplicação: Stack overflow, usuário pressionar ctrl-c ou divisão por zero.

Programação de Computadores 353

Pq precisamos de exceções?! Quando usamos funções nos nossos programas, um erro é

normalmente sinalizado no resultado de retorno da função. Por exemplo, as funções matemáticas, tais como, sin( ) e cos( ) retornam um valor especial para indicar a ocorrência de erro. Para os arquivos em disco , as funções em geral retorna NULL ou 0 para sinalizar erro.

! Podemos fazer os teste após o uso de cada uma delas:

if (alguma_funcao( )==valor_retorno_erro)

//código para manipular o erro

else // procede normalmente

Programação de Computadores 354

! Problemas:! cada retorno de função deve ser examinado no programa"

listagem confusa e difícil de ler. Também não é prático para alguns tipos de funções. Ex: função min( ) " que valor pode sinalizar erro?

! Quando usamos classe existe a chamada implícita de funções. alguma_classe c1,c2,c3;Construtor chamado explicitamente e sem valor de retorno.

! Mais complicação com o uso de biblioteca de classes. Não dá para prever todas as possibilidades de uso. (programador que usaa biblioteca versus desenvolvedor da biblioteca)

! Mecanismos de exceção foram projetados para:! minimizar essas dificuldades ! fornecer uma forma para manipular erros consistente e simples

de implementar

Programação de Computadores 355

Sintaxe! Uma aplicação cria e interage com objetos de uma

determinada classe. De forma geral, a aplicação chama as funções membros da classe sem nenhum problema.

! A aplicação pode cometer um equivoco, causando um erro, detectado por uma função membro" a função informa a aplicação a ocorrência de erro" exceção chamada de “throwing exception” (lançando uma exceção)

! Na aplicação, um código separado é feito para manipular o erro "código chamado manipulador de exceção ou “catch block”(bloco de captura) " pega a exceção lançada por uma função membro.

! qualquer código da aplicação que usa objetos da classe são incluídos no que chamamos de “try block” (bloco de tentativas). Erros gerados nesse bloco são lançados para serem pegos nos blocos de captura.

Programação de Computadores 356

O mecanismo de exceção

dados

funções membro

classe

Erro

Não interage coma classe

código normal

Códigos queinteragem com a

classe

Try bloco

Mostramensagens de

erros, etc.

M a n i p u l a d o r d eexceção (catch block)

aplicação

chamada sem erro

retorno normal

chamada com erro

exceção

Programação de Computadores 357

! Os mecanismos de exceção usas três palavras chaves:throw, catch e try.

! O criador de classes provavelmente também criará um nova espécie de entidade chamada de classe de exceção (“exception class”)class aclasse void main( )

{ ... { trypublic: { aclasse obj1;

class umerro obj1.funcao1( );{ ...}; }

void funcao1 ( ) catch (aclasse::umerro){ if (/* condição de erro*/) { //catch block

throw umerro( ); }} }

};

Programação de Computadores 358

! Temos uma classe chamada aclasse que representa uma classe genérica.

! Na parte pública de aclasse temos uma classe de exceção chamada umerro. As funções membro de aclasse testam erros, se encontrar lançam uma exceção usando a palavra throw seguida do construtor da classe de exceção.

! Na parte main( ) colocamos os comandos que interagem com aclasse no bloco try. Se qualquer comando causar um erro detectado por função membro de aclasse, uma exceção será lançada e o controle passa para o bloco catch que segue imediatamente o bloco try.

Programação de Computadores 359

//vamos usar uma classe vetor alocada estaticamenteclass vetor{ int arranjo[10];

int posicão, //usada para marcar ultima posicao ocupadalimite; //usada para delimitar o arranjo

public:class intervalo { };/* classe de exceção, corpo vazio, usada para conectar o comando throw com o bloco catch*/

int & operator[ ](int n); // sobrecarga do [ ]void insere(int) ; //insere um novo valor no final int retira( ); // ultima posicao ocupada

};

Programação de Computadores 360

vetor::vetor( int n){ if (n>10)

throw intervalo( ); void vetor::insere(int valor)limite = n; { if (posicao==limite-1)arranjo = new int[limite]; throw intervalo( );assert(arranjo!=0); posicao++;posicao= -1; arranjo[posicao]=valor;

} }int& vetor::operator[ ](int n) int vetor::retira( ){ if (n<0 || n>=limite) { if (posicao<0)

throw intervalo( ); throw intervalo( );return arranjo[n]; return arranjo[posicao--];

} }

Programação de Computadores 361

void main( ){ vetor v1(3);

try{ v1.insere(11); v1.insere (22); v1.insere(35);

v1.insere(15); //aqui entrará na exceçãocout<<“Imprimindo o vetor de trás para frente:”;cout<<v1.retira( );cout<<v1.retira( )cout<<v1.retira( );cout<<v1.retira( ); //causará exceção

}catch (vetor::intervalo){ cout<<“valor fora dos limites, vetor cheio ou

vazio”<<endl;}cout<<“Ultimo comando, executado após o catch”<<endl;

}

Programação de Computadores 362

! Vamos modificar a nossa classe para a exceção separar os casos de tentativa de inserir valor num vetor já cheio e tentativa de acessar elemento num vetor vazio.class vetor{ int arranjo[10];

int posicão, //usada para marcar ultima posicao ocupadalimite; //usada para delimitar o arranjo

public:class cheio{ }; class vazio{ }; class intervalo{ };int & operator[ ](int n); // sobrecarga do [ ]void insere(int) ; //insere um novo valor no finalint retira( ); // ultima posicao ocupada

};

Programação de Computadores 363

vetor::vetor( int n){ if (n>10)

throw intervalo( ); void vetor::insere(int valor)limite = n; { if (posicao==limite-1)arranjo = new int[limite]; throw cheio( );assert(arranjo!=0); posicao++;posicao= -1; arranjo[posicao]=valor;

} }int& vetor::operator[ ](int n) int vetor::retira( ){ if (n<0 || n>=limite) { if (posicao<0)

throw intervalo( ); throw vazio( ); return arranjo[n]; return arranjo[posicao--];

} }

Programação de Computadores 364

void main( ){ vetor v1(3);

try{ v1.insere(11); v1.insere (22); v1.insere(35);

v1.insere(15); //aqui entrará na exceçãocout<<“Imprimindo o vetor de trás para frente:”;cout<<v1.retira( );cout<<v1.retira( )cout<<v1.retira( );cout<<v1.retira( ); //causará exceção

}catch (vetor::cheio) { cout<<“ vetor cheio “<<endl;}catch( vetor::vazio) { cout<<“ vetor vazio”<<endl;}catch (vetor::intervalo){ cout<<“valor fora dos limites permitidos”<<endl;}

cout<<“Ultimo comando, executado após o catch”<<endl;}

Programação de Computadores 365

! Exceção na classe medida inglesa "o objeto tem um valor inteiro para pés e um valor real para polegadas. O valor de polegadas deve ser sempre menor que 12 e isso não foi levado em consideração quando escrevemos a classe. Vamos reescrever essa classe e usarmos exceção para manipular esse tipo de erro.

Programação de Computadores 366

#include <iostream.h>class med_inglesa{ int pes; float polegadas;public:classe excecao { }; //classe excecaomed_inglesa() { pes=0; polegadas=0.0;}med_inglesa (int p, float pol){ if (polegadas>=12.0) throw excecao( );

pes= p; polegadas = pol;}void entra_valores( ){ char ch; cin>>pes>>ch>>ch>>polegadas>>ch;

if (polegadas>=12.0”) throw excecao( ); }friend ostream& operator<<(ostream&, const med_inglesa&);

};

Programação de Computadores 367

void main( ){ med_inglesa distancia1(17,3.5), distancia2;try { cout<<"entre com a distancia no formato ingles:";distancia2.entra_valores( );cout<<“Distância1=“<<distacia1; cout<<endl<<“Distância2=“<<distancia2;

}catch(med_inglesa::excecao){ cout<<“Erro de iniciacao:Polegadas pode ser no

maximo 12”;}

}É obvio que nesse caso seria muito mais produtivo manipular o erro do usuário de outra forma, mas serve como exemplo.

Programação de Computadores 368

Exceção com argumentos! Podemos fazer que a exceção sinalize de forma

mais clara para o usuário o motivo de sua ocorrência

! Também é possível que a causa de exceção venha de diferentes funções e portanto podemos dizer qual delas causou o problema

! A tratamento de exceção envolve a transferência do controle para o manipulador e a criação de um objeto da classe exceção chamando seu construtor (throw excecao( );).

! Podemos adicionar dados a classe exceção e iniciar seus valores quando criamos o objeto.

Programação de Computadores 369

#include <iostream.h>class med_inglesa { int pes; float polegadas;public:classe excecao //classe excecao{ public:

char* origem; float valor;excecao(char* o, float f) { origem = o; valor = f; }

};med_inglesa() { pes=0; polegadas=0.0;}med_inglesa (int p, float pol){ if (polegadas>=12.0)

throw excecao(“construtor com 2 argumentos”, pol);pes= p; polegadas = pol;

}void entra_valores( ){ char ch; cin>>pes>>ch>>ch>>polegadas>>ch;

if (polegadas>=12.0”) throw excecao(“função que le valores”, polegadas );

}friend ostream& operator<<(ostream&, const med_inglesa&);

};

Programação de Computadores 370

void main( ){ med_inglesa distancia1(17,3.5), distancia2;

try { cout<<"entre com a distancia no formato inglês:";

distancia2.entra_valores( );cout<<“Distância1=“<<distacia1;cout<<endl<<“Distância2=“<<distancia2;

}catch(med_inglesa::excecao e){ cout<<“Erro de iniciação em “<< e.origem

<<“\n Valor de polegadas=<<e.valor<<“ muito grande o máximo é 12”;

}}