next up previous contents
Next: Herança Up: Encapsulação Previous: Amizade   Sumário

Tratamento de exceções

Em linguagens de programação tradicionais, assim como C, o tratamento de erros é geralmente realizado na forma de códigos de falha retornados por funções. Um exemplo típico desta abordagem são as indicações geralmente retornadas por system calls: por exemplo, quando se executa a rotina do sistema operacional para abrir um arquivo, open, um valor de retorno positivo indica sucesso da operação, enquanto que um valor negativo (-1) indica uma condição de erro (arquivo especificado não existe, usuário não tem permissão de acesso, sistema não consegue abrir mais arquivos). Todos as possíveis condições de erro retornadas por uma rotina do sistema devem ser testadas -- a não detecção de um erro no momento do retorno da rotina pode ser catastrófica para a aplicação e, em alguns casos, para o sistema como um todo.

De certo modo, mecanismo usual de manipulação de erros fere o conceito de encapsulação de C ++. Um erro, o qual pode ter ocorrido em um nível bem interno da aplicação, tem que ser propagado até um ponto onde uma decisão de o que fazer possa ser tomada -- muitas vezes, bem longe da classe responsável pelo erro. É parte do princípio de encapsulação e de boa programação que cada classe seja capaz de lidar com seus erros. O efeito de um erro deve estar restrito à classe que o geral, e não se propagar pelo sistema ``derrubando'' outras classes em um efeito dominó. Duas características de um sistema robusto é que todas as falhas do sistema devem ser relatadas e, caso a falha seja tão séria que comprometa a continuação da execução da aplicação, o processo da aplicação deve ser terminado.

O mecanismo que C ++ oferece para lidar com a manipulação de situações como esta é o tratamento de exceções3.3 As construções suportadas para este fim são try, throw e catch.

Um bloco try delimita um segmento do programa onde alguma coisa de errado pode acontecer. Se algum erro acontece durante a execução deste bloco, o comando throw (similar a um return) é chamado com um argumento que pode ser qualquer objeto; o mais comum é retornar com um inteiro. O valor enviado por throw é capturado por um (ou mais de um) bloco catch, na mesma rotina que contém o bloco try. No corpo do bloco catch se define a ação a ser tomada em caso de ocorrência de erros.

O exemplo a seguir ilustra a utilização deste mecanismo.

indentation

// rotina onde erros serao tratados
int f() {
// bloco onde erro pode ocorrer
try {
return g(); // este e o bloco try
}

// excecoes, se houver, sao tratadas aqui
catch (int x) { // aqui, se um inteiro foi atirado
// trata excecao...
}

catch (float x) { // ou aqui, se um float foi atirado
// trata excecao...
}

// se algo diferente foi atirado, sera atirado para a
// a rotina que chamou f()
}

// rotina onde erro pode ocorrer
int g() {
if (Erro_Que_Eu_Nao_Sei_Tratar_Ocorreu) {
throw 2; // atira um inteiro
}

// continua, se tudo bem...
}


next up previous contents
Next: Herança Up: Encapsulação Previous: Amizade   Sumário
Ivan Luiz Marques Ricarte 2001-06-01