Você está na página 1de 2

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.

// 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...


}

Você também pode gostar