Anda di halaman 1dari 29

Universidade Federal de Campina Grande

Centro de Engenharia Eltrica e Informtica


Departamento de Sistemas e Computao

Relatrio de Seminrio de Pesquisa

Ttulo
Manipulao de Erros e Excees

Disciplina
Tcnicas de Programao

Professor
Jos Eustquio Rangel de Queiroz
rangel@dsc.ufcg.edu.br, rangeldequeiroz@gmail.com

Equipe
Daniel Ribeiro do Carmo Filho
Danilo Gomes de Andrade
Lucas Farias Martins
Rogerio Moreira Almeida

{daniel.filho, danilo.andrade lucas.martins, rogerio.almeida}@ee.ufcg.edu.br

Campina Grande PB
Maro de 2017
_____________________________
Jos Eustquio Rangel de Queiroz
Professor

_____________________________
Daniel Ribeiro do Carmo Filho

_____________________________
Danilo Gomes de Andrade

_____________________________
Lucas Farias Martins

_____________________________
Rogerio Moreira Almeida

Equipe
SUMRIO

1 Introduo ...................................................................................... 4

2 Objetivos ...................................................................................... 5

3 Fundamentao Terica .................................................................. 5

3.1 Erros x excees .................................................................. 5

3.2 Mecanismo para manipulao de erros e excees ........... 6

3.2.1 DESEMPILHAMENTO ......................................................... 7

3.2.2 FUNCIONAMENTO ......................................................... 7

3.3 return x throw ............................................................................ 8

3.4 Classes de exceo ................................................................... 9

3.2.1 DA BIBLIOTECA PADRO ................................................ 9

3.2.2 DO PROGRAMADOR ......................................................... 10

3.5 Cabealho <exception> ......................................................... 11

3.6 Relanamento de exceo ......................................................... 11

3.7 unexpected() e terminate() ................................................ 12

3.8 Especificaes de exceo ......................................................... 12

3.9 Apontadores inteligentes ......................................................... 13

3.10 Erros de entrada e sada ......................................................... 13

4 Consideraes Finais .................................................................. 14

Referncias Bibliogrficas ...................................................................... 14

Anexos ...................................................................................... 15

Apndices ...................................................................................... 19
4

1 Introduo
Neste relatrio ser apresentado e discutido o tema "Manipulao de Erros e
Excees" visando melhoria dos programas desenvolvidos na linguagem de
programao C++. Dessa forma, ser possvel criar programas evitando ou
contornando erros inesperados, bem como avisar que h algo errado e que
medidas corretas devem ser executadas. Esses detalhes tornam os programas
mais bem preparados e desenvolvidos que outros, satisfazendo melhor as
exigncias do mercado.
Elaborao do documento:
i. Introduo nesta seo so descritos os interesses e a importncia do
tema;
ii. Objetivos na segunda seo sero apresentados os objetivos especficos
e geral deste relatrio;
iii. Fundamentao Terica na terceira seo ser desenvolvida uma
explicao do tema;
iv. Consideraes Finais na quarta seo sero apresentadas as concluses
obtidas da pesquisa;
v. Referncia Bibliogrfica nessa seo esto listadas as fontes da pesquisa;
vi. Anexos nessa seo esto os cdigos de outros autores adaptados;
vii. Apndices nessa seo esto os cdigos elaborados pelo autor.
importante notar que o uso de equipamentos e aplicativos criados pelo
ser humano est cada vez mais intrnseco vida atual. Eles so utilizados
diariamente para facilitar e possibilitar a realizao de diversas atividades, como
numa empresa armazenando dados ou num avio voando. Alm de entreter com
jogos, eles esto presentes desde uma lmpada que ilumina a casa, at um satlite
que envia e recebe sinais constantemente.
flagrante, outrossim, que muitas vezes a vida de pessoas e o
funcionamento de empresas dependem da eficincia e boa execuo desses
equipamentos e aplicativos, quando erros so, no apenas inconvenientes, mas
inadmissveis. Por isso so feitos diversos testes e prevenes para evitar
tragdias como a que ocorreu em Alcntara no lanamento de um foguete, quando
21 pessoas pereceram devido a um acidente.
Deve-se a esses fatos uma das maiores importncias do tratamento de
erros e excees, ele no apenas deixa o programa mais elegante, como tambm
o deixa mais independente a eventos condicionados pelo usurio e indesejveis ao
5

programa. Desse modo, evita-se que erros irreversveis aconteam e garante-se


uma execuo limpa e de boa funcionalidade, exibindo mensagens e impedindo ou
finalizando o programa caso algo no esteja de acordo com o que se espera.

2 Objetivos
A pesquisa ora documentada tem como objetivo geral trazer conhecimentos acerca
da Manipulao de Erros e Excees, esclarecendo sua funcionalidade e uso e
garantindo que se evitem eventos os quais possam ocasionar prejuzos ou
desastres. Dentre os objetivos especficos da referida pesquisa podem ser citados:
i. Expor o contedo de forma simples e acessvel;
ii. Descrever como funcionam os cdigos da manipulao de erros e excees
em C++;
iii. Exibir exemplos e aplicaes.

3 Fundamentao Terica
As linguagens de programao mais atuais j possuem mecanismos para evitar
problemas causados por eventos inesperados. No diferente para o C++, cujos
recursos podem ser utilizados para contornar uma situao que traria problemas.
Inicialmente sero apresentados os conceitos bsicos de Manipulao de Erros e
Excees e, ento, adentrar-se- mais no tema.
Ao iniciar uma funo com um valor que foge regra dela ocorre um
resultado inesperado, como o exemplo no Apndice A Fatorial Negativo, nada se
pode afirmar quanto a que ser exibido durante a execuo do programa visto que
no existe fatorial de nmero negativo, mas pode se utilizar os comandos try,
throw e catch para evitar que essa exceo ocorra. Para compreender tudo
corretamente, necessrio, preliminarmente, saber de alguns detalhes os quais
sero explicados a seguir.

3.1 Erros x excees


De acordo com Stroustrup (1985) e Deitel (2005) as definies de tratamento de
erros e excees tm significados diferentes. Sabe-se que erros so
acontecimentos indesejveis que podem ou no prejudicar o programa, e existem
diversos mecanismos para manipul-lo e garantir uma segurana, sendo um dos
principais por meio de excees indicaes de um problema que tem a
6

possibilidade de acontecer transferindo as informaes indicadas do ponto em


que o erro detectado ao em que pode ser tratado, continuando a aplicao ou
finalizando o programa elegantemente. Isso permite separar o cdigo do programa
do de manipulao de erros, facilitando a inteligibilidade do cdigo.

3.2 Mecanismo para manipulao de erros e excees


Apesar de existir diversos modos rudimentares os quais permitem evitar o
acontecimento de excees, como o uso de funes para simplesmente finalizar o
programa (terminate(), exit() ou abort()) ou retornar um valor para indicar erro
(funo booleana). O uso do mecanismo desenvolvido especificamente para isso
muito mais eficiente, sendo um funcionamento simples da manipulao de erros e
excees em C++ explicado desta forma:
i. Utilizando o bloco try{};
ii. Lanar a exceo encontrada com o operador throw;
iii. Capturar a exceo lanada no bloco catch(){}.
Desse modo, o programa lana para o catch(){} uma exceo quando um
erro seria encontrado. Ao lan-la, o programa pula, como foi dito por Prata
(2012), tudo que estiver depois do throw, finalizando o escopo, e cai no
respectivo catch(){}, continuando o programa a partir deste ponto.
Pode-se comparar o mecanismo com um jogo de basquete: tentar
arremessar a bola para a cesta como utilizar o bloco try{} para tentar lanar
uma exceo; jogar a bola como utilizar o throw para lanar uma exceo para
um bloco catch; o bloco catch(){} como a cesta, que pode ou no receber a bola.
Veja o Quadro 1 para sintetizar a funo de cada parte do mecanismo.
Quadro 1 try, throw e catch

try{} throw catch(){}


o bloco onde h um cdigo e o recurso utilizado para lanar a o bloco onde as excees
pode lanar excees exceo encontrada no bloco try{} sero manipuladas e as
especficas. Sempre seguido para o bloco catch(){}. devidas medidas executadas.
por um ou mais blocos
catch(){}.
Sintaxe: Sintaxe: Sintaxe: (Logo aps o try{} ou
try{cdigo com possvel erro} throw alguma_exceo; outro catch(){})
catch(alguma_exceo){
cdigo das medidas }
Fonte: Compilado pelo prprio autor.

A vantagem de utilizar este mecanismo a possibilidade de tratar diversos


erros de vrias formas diferentes, com um tratamento para cada exceo,
tornando o programa mais eficiente e prova desses erros, alm de separar o
7

cdigo do programa do cdigo do tratamento do erro, tornando o programa mais


inteligvel. Isso se d devido s seguintes possibilidades:
i. Utilizar um bloco try{} dentro de outro;
ii. Haver mais que um throw dentro de um bloco try(){};
iii. Colocar mais que um catch(){} para cada bloco try{};
iv. Capturar qualquer tipo de exceo com o bloco catch(...){} aps os
outros;
Observe o Apndice B Exemplos do mecanismo, cuja exibio ser
Classe instanciada 1, Classe instanciada 2, Destrutor chamado de 2, Destrutor
chamado de 1, int capturado, Classe instanciada 3, Capturado pelo catch(...),
Destrutor chamado de 3, evidenciado o que foi mostrado.

3.2.1 DESEMPILHAMENTO
Com o fluxo do programa, ocorre o empilhamento de blocos e funes, mas quando
uma exceo lanada, o processo de desempilhamento iniciado. Dessa forma,
o escopo atual finalizado, se ele for um bloco try{}, busca um catch(){}
correspondente, se no encontrar ou no for um bloco try{}, o desempilhamento
reiniciado.
Ao executar o cdigo do Apndice C Desempilhamento possvel
perceber o caminho do programa, desde o empilhamento ao desempilhamento.

3.2.2 FUNCIONAMENTO
importante saber que, de acordo com Deitel (2005), se uma exceo ocorrer,
ela lanada e o bloco try{} finalizado, ento as excees procuram um
catch(){} pela ordem de cima para baixo e do try{} mais interno para o mais
externo (desempilhamento), comparando o tipo de exceo lanado com o tipo de
parmetro de exceo dos blocos catch(){}, ocorre a correspondncia se os tipos
forem idnticos ou se o tipo lanado for de uma classe derivada do tipo do
parmetro, contudo, caso nenhum catch(){} capture a exceo, a funo
unexpected() chamada.
Alm disso, vale ressaltar que o programa no retorna ao ponto em que a
exceo ocorreu, mas se excees no ocorrerem no bloco try{}, seus blocos
catch(){} sero ignorados.
Dessa forma, voltando ao problema inicial do fatorial de um nmero
negativo, pode-se, ento, construir um programa mais robusto que exibe uma
8

mensagem de erro ao tentar fazer essa operao, como exemplificado no


Apndice D Fatorial com Manipulao de Erros, exibindo a mensagem Nao ha
fatorial de numero negativo. Note nesse exemplo o uso de cerr, que utilizado
para exibir as mensagens de erro, diferente do cout, que utilizado para exibir as
mensagens do programa.

3.3 return x throw


possvel comparar um return a um throw j que possuem uma funo de "pular"
semelhante. Por exemplo, ao haver uma situao em que uma funo chama outra
funo e assim por diante, enquanto o return numa funo pularia para a que a
chamou, o throw pularia direto para o catch(){} do try{} em que se localiza,
no importando por quantas funes passou antes. Veja nos Diagramas 1 e 2 a
comparao return x throw.
Diagrama 1 return

void func_1(){... void func_2(){... void func_3(){... void func_4(){


func_2(); func_3(); func_4();
... ... ... ...
return; return; return;
} } } }

Fonte: Compilado pelo prprio autor.

Diagrama 2 throw

void func_1(){ void func_2(){... void func_3(){... void func_4(){...


try{... func_3(); func_4(); throw exceo;
func_2(); ... ... ...
return; return; return;
}catch(excecao){} } } }
}

Fonte: Compilado pelo prprio autor.

necessrio perceber que cada uma tem sua forma e objetivo, desse
modo, ambas tm sua importncia de acordo o resultado desejado. J que o return
pode ser utilizado sempre que quiser retornar algo para a funo que o chamou e
o throw sempre que quiser lanar uma exceo para o respectivo catch(){},
percebemos que o segundo ideal para a manipulao de erros e excees.
Observe que no Apndice E throw x return mostra a diferena aplicada
entre o throw e o return e ser exibido o fluxo do programa: Entrando em func1,
9

Entrando em func2, Entrando em func3, Retornando de func3, Retornando de


func2, Retornando de func1,
Entrando em func1, Entrando em func2, Entrando em func3, Lancando de func3,
Capturado..

3.4 Classes de exceo


As classes de exceo auxiliam para separar os tipos de exceo lanadas. Isso
permite que o programador trate de cada exceo especfica, dessa forma, o
programa pode evitar mais erros organizadamente.

3.4.1 DA BIBLIOTECA PADRO


O cabealho <exception> define diversas classes de exceo. Nele, declarada a
classe abstrata exception, que classe bsica, seja direta, seja indiretamente, de
todas as classes de exceo padro. Diversas outras so definidas na biblioteca
<stdexcept> que so derivadas de duas categorias (sendo da segunda a maioria):
i. Erros de Execuo (Runtime Errors) classe runtime_error so
excees as quais voc no pode detectar ou prevenir apenas por analisar
o cdigo. Acontecem por condies as quais voc pode antecipar, mas no
prevenir. Como exemplo de Erros de Execuo, temos:
overflow_error quando o resultado de um clculo excede o maior valor
representvel daquele tipo;
underflow_error quando o resultado de um clculo menor que o menor
valor representvel (negativo);
range_error quando o resultado de um clculo est fora do alcance de
uma funo, sem necessariamente ser um overflow ou um underflow.
ii. Erros Lgicos (Logical Errors) classe logic_error resultam de erros
de programao. Como exemplo de Erros Lgicos, temos:
domain_error caso o argumento esteja fora do domnio esperado;
invalid_argument caso um argumento invlido seja passado;
length_error caso no haja espao suficiente para realizar uma ao;
out_of_range caso numa matriz ou vetor, por exemplo, seja inserido um
ndice invlido. Erros de indexao.
Alm dessas, h tambm a classe bad_alloc, a qual est no cabealho
<new>, ela indica que no h mais memria disponvel para alocar com o new,
antigamente, quando isto acontecia, era retornado um apontador nulo. Um
10

mecanismo interessante utilizar a funo set_new_handler(novo_tratador) para


sempre que for lanar a exceo bad_alloc chamar a funo novo_tratador(). Essa
funo deve finalizar o programa, liberar espao de memria ou lanar a exceo
bad_alloc.
Algumas das outras classes derivadas da classe bsica exception so:
i. nested_exception (do C++11) captura e armazena excees, permitindo
aninh-las;
ii. bad_cast lanada quando se tenta fazer um casting errado;
iii. bad_typeid do cabealho <typeid>, lanada quando se tenta mostrar o
nome de um apontador de uma classe polimrfica que recebe o valor nulo;
iv. bad_exception se colocada na lista throw, a funo unexpected pode
lan-la.
Vale salientar, outrossim, que na classe bsica exception h o construtor
que recebe uma string com a mensagem de erro, o destrutor e a funo membro
virtual what() que retorna a string.
necessrio tomar cuidado quanto ordem dos blocos catch porque, caso
um que capture a classe bsica venha antes, todas as excees das classes
derivadas sero capturadas. Observe o Diagrama 3 com algumas das hierarquias.

Diagrama 3 Excees Padro

exception

runtime_error logic_error

overflow_error range_error invalid_argument domain_error

underflow_error length_error out_of_range

bad_typeid bad_alloc bad_cast bad_exception

Fonte: Adaptado de DEITEL e DEITEL, 2005

Veja no Anexo A Classes de Exceo da Biblioteca Padro a aplicao de


algumas das excees padro e suas funes, espera-se que a mensagem exibida
seja std::bad_typeid std::bad_cast std::bad_alloc vector::_M_range_check
bitset::_M_copy_from_ptr.

3.4.2 DO PROGRAMADOR
evidente a mirade de classes existentes na biblioteca padro para auxiliar no
11

lanamento de uma exceo adequada, mas ainda possvel, caso seja de


interesse do programador, criar uma classe para utiliz-la com o objetivo de lanar
uma exceo, podendo ou no ser derivada de outra classe.
Caso a classe seja derivada de uma classe de exceo da biblioteca padro,
haver a possibilidade de inicializar o construtor da classe bsica com a mensagem
de erro ou sobrescrever a funo what() para exibir essa mensagem.

3.5 Cabealho <exception>


Alm das funes mencionadas em 3.5 unexpected e terminate, o cabealho
exception define o typedef exception_ptr o qual um apontador que manipula
um objeto de exceo lanado e as funes:
i. uncaught_exception() ou uncaught_exceptions() (do C++17) identifica se
o tratamento de excees est sendo utilizado;
ii. make_exception_ptr() (do C++11) cria um exception_ptr de um objeto
de exceo;
iii. current_exception() (do C++11) captura a exceo atual no
exception_ptr;
iv. rethrow_exception() (do C++11) lana o objeto de exceo do
exception_ptr capturado anteriormente;
v. throw_with_nested() (do C++11) lana seu argumento como
nested_exception;
vi. rethrow_with_nested() (do C++11) lana a exceo de uma
nested_exception;
Observe no Anexo B Funes do Cabealho <exception> a aplicao de
alguns um deles, esperado que o programa exiba a mensagem excecao
capturada, mas continuando... (depois da excecao), excecao capturada: excecao
de logica, excecao capturada: logic_error, segunda, aninhada: primeira.

3.6 Relanamento de exceo


Caso o bloco try{} esteja dentro de outro, h a possibilidade de relanar uma
exceo se necessrio, para tanto, basta utilizar o operador sem nada throw;
dentro do catch(){}. Dessa forma, ser possvel procurar outra correspondncia
nos blocos catch(){} do try{} mais externo.
Observe no Apndice F Relanamento de Exceo que a exceo
capturada pelo bloco catch(){} ser relanada e capturada pelo do bloco try{}
12

mais externo e a mensagem exibida ser No primeiro catch(){}, relancando a


excecao. No segundo catch(){}.

3.7 unexpected() e terminate()


Como j mencionado, um exemplo de suas utilizaes quando nenhum catch(){}
captura a exceo. Dessa forma a funo unexpected() (at C++17) chamada,
a qual, por padro, chama terminate(), que, tambm por padro, chama abort(),
a qual resulta na finalizao do programa.
Ambas esto no cabealho <exception> e alm delas h as funes:
i. set_unexpected(nome_da_nova_funcao_unexpected) (at o C++17) faz
chamar a nova funo ao invs da unexpected() padro;
ii. get_unexpected() (do C++11 at o C++17) retorna a funo
unexpected() atual;
iii. set_terminate(nome_da_nova_funo_terminate) faz chamar a nova
funo ao invs da terminate();
iv. get_terminate() (do C++11) retorna a funo terminate() atual.
Dessa forma, possvel emitir mensagens de aviso do erro e proteger o
programa antes da sua finalizao. Alm disso, pode-se manipular qual funo
ser chamada de acordo com o fluxo do programa.
Vale salientar que, mesmo que nas novas funes no se finalize o
programa, abort() ser chamada, e que essas funes set retornam um apontador
para as ltimas funes unexpected() e terminate(), podendo ser restauradas
posteriormente.
A funo terminate() chamada por padro, por exemplo, quando:
i. No h correspondncia com os blocos catch(){};
ii. Tenta lanar uma exceo num destrutor durante o desempilhamento;
iii. unexpected() chamada;
iv. Tenta relanar uma exceo fora de um bloco catch(){}.

3.8 Especificaes de exceo (lista throw)


Indicam os tipos de excees que uma funo pode lanar. Sintaxe:
<tipo_retorno_funcao> <nome_funcao>() throw(<tipo_possivel_de_lancar>);.
H duas formas de especificar:
i. throw() ou noexcept indica que a funo no pode lanar nada;
13

ii. throw(tipo1,tipo2) indica que somente os tipos indicados podem ser


lanados.
Caso a funo lance algo que no esteja de acordo com a especificao, a
funo unexpected() chamada. Contudo, se na lista throw houver o tipo
bad_exception, ser possvel lan-la da funo unexpected() para ser capturada
e continuar o programa, para tanto, basta utilizar o operador sem nada throw;.
Observe no Apndice G Lista throw a mensagem Na nova unexpected,
bad_exception capturado, Na nova unexpected, Na nova terminate, exibida e
ento o programa finalizado, pois sempre que algo fora da lista throw lanada,
o programa chama a funo unexpected().

3.9 Apontadores inteligentes


O uso de apontadores inteligentes garante que toda memria alocada seja
liberada, dessa forma, o vazamento de memria evitado caso haja o lanamento
de uma exceo antes do operador delete.
Atualmente, h quatro tipos de apontadores inteligentes, auto_ptr<>,
unique_ptr<>, shared_ptr<> e weak_ptr<>, todos definidos no cabealho
<memory> no namespace std.
Observe no Apndice H Apontadores Inteligentes que, como uma exceo
foi lanada antes de executar o operador delete, ocorre um vazamento de
memria, contudo, esse erro pode ser corrigido ao utilizar o apontador inteligente
auto_ptr<>, dessa forma, a sada esperada Criando nova: 1, Destruindo nova:
1, Excecao capturada, Criando nova: 2, Excecao capturada, Criando nova: 3,
Destruindo nova: 3, Excecao capturada,.

3.10 Erros de entrada e sada


Sabe-se que o fluxo de entrada e sada (I/O Stream) no lana, por padro, erro
algum, mas, caso algo errado acontea, pode se utilizar as mscaras de exceo
para evitar problemas.
Sua sintaxe, <fluxo>.exception(<tipo_de_exceo>), onde o fluxo pode
ser um objeto do tipo ifstream, um cin, um cout, entre outros, e os principais tipos
de exceo so o ios_base::failbit para os erros de lgica, ou seja, caso o tipo
inserido seja diferente do esperado, e ios_base::badbit para os erros de leitura ou
escrita. Dessa forma, ser lanada a exceo do tipo ios_base::failure, quando
ocorrer o erro, permitindo finalizar o programa e evitar problemas ou perda de
14

dados.
Observe no Apndice I Excees de Entrada que quando um inteiro for
inserido, o programa continuar normalmente, mas, caso algo diferente seja
inserido, uma exceo lanada, e o programa, finalizado.

4 Consideraes Finais

Observa-se, portanto, que a Manipulao de Erros e Excees um detalhe


importante para transformar um bom programa em um mais robusto e preparado
para ser utilizado pelas pessoas. Ela tambm evita que erros graves aconteam,
assegurando o programa e podendo finaliz-lo com mais "elegncia".

A Manipulao de Erros e Excees veio para melhorar significativamente os


programas, de forma a garantir uma confiana maior nos que a utilizam porque
erros os quais podem ser irreversveis poderiam acontecer e causar uma mirade
de problemas

Espera-se que, a partir desta pesquisa, seja possvel compreender e aplicar


o uso do mecanismo de tratamento de erros do C++, de forma a ajudar a melhorar
a qualidade dos programas criados doravante.

Referncias Bibliogrficas
LISCHNER, Ray. Exploration 43: Exceptions. In:_____. Exploring C++: The
Programmer's Introduction to C++. United States of America: Apress, 2009.
p.357-371.

PRATA, Stephen. Friends, Exceptions and more: Exceptions. In:_____. C++


Primer Plus: Developer's Library, 6th Ed. United States of America: Addison-
Wesley, 2012. p.896-933.

SAVITCH, Walter. Exception Handling. In:_____. Absolute C++, 5th Ed. United
States of America: Addison-Wesley, 2013. p.825-855.

STROUSTRUP, Bjarne. Exception Handling. In:_____. The C++ Programming


Language, 4th Ed. United States of America: Addison-Wesley, 2013. p.343-387.

Exceptions. Disponvel em < www.cplusplus.com/doc/tutorial/exceptions/>.


ltimo acesso: 13 de maro de 2017.

Standard library header <exception>. Disponvel em <


en.cppreference.com/w/cpp/header/exception>. ltimo acesso: 13 de maro de
2017.
15

Anexo A Classes de Exceo da Biblioteca Padro

//Anexo A - Classes de Exceo da Biblioteca Padro


//ADAPTADO DE: WWW.CPPREFERENCE.COM E WWW.CPLUSPLUS.COM
#include <iostream>
#include <typeinfo>
#include <new>
#include <vector>
#include <stdexcept>
#include <bitset>

struct S { // The type has to be polymorphic


virtual void f();};

struct Foo { virtual ~Foo() {} };

int main()
{
S* p = NULL;
try {
std::cout << typeid(*p).name() << '\n';
} catch(const std::bad_typeid& e) {
std::cout << e.what() << ' ';
}

Foo b;
try {
S& d = dynamic_cast<S&>(b);
} catch(const std::bad_cast& e)
{
std::cout << e.what() << ' ';
}

try{
int* myarray= new int[100000000000000000000];
} catch (std::bad_alloc& ba)
{
std::cerr << ba.what() << ' ';
}

std::vector<int> myvector(10);
try {
myvector.at(20)=100; // vector::at throws an out-of-range
}
16

catch (const std::out_of_range& oor) {


std::cerr << oor.what() << ' ';
}

try {
// bitset constructor throws an invalid_argument if initialized
// with a string containing characters other than 0 and 1
std::bitset<5> mybitset (std::string("01234"));
}
catch (const std::invalid_argument& ia) {
std::cerr << ia.what() << ' ';
}
}
17

Anexo B Funes do Cabealho <exception>


// Anexo B - Funes do cabealho <exception>
//para abrir no c++ shell use o link: cpp.sh/865y
#include <iostream> // std::cout
#include <exception> // std::exception_ptr, std::current_exception,
std::rethrow_exception
#include <stdexcept> // std::logic_error

// lana uma exceo aninhada em outra


void throw_nested() {
try {
throw std::logic_error ("primeira");
} catch (const std::exception& e) {
std::throw_with_nested(std::logic_error("segunda"));
}
}

// exibe what() recursivamente


void print_what (const std::exception& e) {
std::cout << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch (const std::exception& nested) {
std::cout << "aninhada: ";
print_what(nested);
}
}

int main () {
std::exception_ptr ptr;
try {
throw std::logic_error("excecao de logica"); // throws
} catch(const std::exception& e) {
ptr = std::current_exception();
std::cout << "excecao capturada, mas continuando...\n";
}

std::cout << "(depois da excecao)\n";

try {
std::rethrow_exception (ptr);
} catch (const std::exception& e) {
std::cout << "excecao capturada: " << e.what() << '\n';
18

auto p = std::make_exception_ptr(std::logic_error("logic_error"));

try {
std::rethrow_exception (p);
} catch (const std::exception& e) {
std::cout << "excecao capturada: " << e.what() << '\n';
}

try {
throw_nested();
} catch (std::exception& e) {
print_what(e);
}
return 0;
}
19

Apndice A Fatorial Negativo

//Apndice A - Fatorial Negativo


#include <iostream>
using namespace std;

//funo que retorna o fatorial de um nmero


int fatorial(int numero){
if(numero==0||numero==1)
return 1;
return numero*fatorial(numero-1);
}

int main(int argc, char *argv[])


{
//qual seria a sada?
cout << fatorial(-2);

return 0;
}
20

Apndice B Exemplos do Mecanismo


//Apndice B - Exemplos do mecanismo
#include <iostream>
using namespace std;

//classe para indicar a finalizao de seu escopo


class finalizacao{
int i;
public:
finalizacao(int i){
this-> i = i;
cout<< "Classe instanciada " << i << ", ";
}
~finalizacao(){cout << "Destrutor chamado de " << i << ", ";}
};

int main(int argc, char *argv[])


{
try{
try{
finalizacao a(1);
try{
finalizacao b(2);
throw 12;
//como o primeiro throw j lanou a exceo,
//o segundo ignorado
//ao lanar a exceo o escopo finalizado
throw "erro";
}catch(char){cout << "char capturado, ";}
catch(char*){cout << "char* capturado, ";}
//ser capturada a exceo
}catch(int){cout << "int capturado, ";}
//observe que qualquer tipo pode ser lanado, inclusive uma classe
throw finalizacao(3);
}catch(...){cout << "Capturado pelo catch(...), ";}

return 0;
}
21

Apndice C Desempilhamento
//Exemplo 08 - O desempilhamento
#include <iostream>
#include <exception> //std::exception

using namespace std;

void funcao_1();
void funcao_2();

int main(){

try{
cout << "Primeiro bloco try{}" << endl;

try{
cout << "Segundo bloco try{}" << endl;

funcao_1();

cout << "Comando No-Exibido na tela" <<endl;

}catch(int &x){

cerr << "Um inteiro foi capturado no bloco catch(int){}"


<< " do primeiro bloco try{}" << endl;

}catch(double &y){

cerr << "Um double foi capturado no bloco catch(double)"


<< "{} do primeiro bloco try{}" << endl;
Apndice C - Desempilhamento
}
cout << "Comando No-Exibido na tela" <<endl;

}catch( exception & e ){

cerr << "\nUm objeto exception foi capturado no bloco catch"


<< "(exception){} do segundo bloco try{}" << endl;

}catch(...){

cerr << "\nAlgo foi capturado no bloco catch(...){}"


<< " do segundo bloco try" << endl;
22

cout << "\nO fluxo do programa e retomado apos o ultimo bloco"


<< " catch(){} pertencente ao try{} finalizado" << endl;

return 0;
}

void funcao_1(){

cout << "Entra na Funcao 1" << endl;

funcao_2();

cout << "Comando No-Exibido na tela" <<endl;


}

void funcao_2(){

cout << "Entra na Funcao 2" << endl << endl


<< "Lancando uma excecao do tipo exception" << endl <<endl
<< "Finaliza a funcao 2" << endl
<< "Finaliza a funcao 1" << endl
<< "Finaliza o segundo try{}" << endl
<< "Procura uma correspondencia com o parametro dos catch(){}" << endl
<< "Finaliza o primeiro try{}" << endl
<< "Procura uma correspondencia com o parametro dos catch(){}" << endl;

throw exception();

cout << "Comando No-Exibido na tela" <<endl;


}
23

Apndice D Fatorial com Manipulao de Erros


//Apndice D - Fatorial com Manipulao de Erros
#include <iostream>
#include <string>
using namespace std;

//funo que retorna o fatorial de um nmero


int fatorial(int numero){
if(numero<0)
throw "Nao ha o fatorial de numero negativo";
if(numero==0||numero==1)
return 1;
return numero*fatorial(numero-1);
}

int main(int argc, char *argv[])


{
//qual seria a sada?
try{
cout << fatorial(-2);
}catch(const char * erro){
cerr << erro;
}

return 0;
}
24

Apndice E throw x return


//Apndice E - throw x return
#include <iostream>
using namespace std;

void func3(int i){


cout << "Entrando em func3, ";
if(i==1){
cout << "Lancando de func3, ";
throw i;
}
cout << "Retornando de func3, ";
};

void func2(int i){


cout << "Entrando em func2, ";
func3(i);
cout << "Retornando de func2, ";
};

void func1(int i){


cout << "Entrando em func1, ";
func2(i);
cout << "Retornando de func1, ";
return;
};

int main(int argc, char *argv[])


{
try{
func1(0);
cout << endl;
func1(1);
}catch(int){
cerr << "Capturado.";
}
return 0;
}
25

Apndice F Relanamento de Exceo


//Apndice F - Relanamento de exceo
#include <iostream>
using namespace std;

int main(int argc, char *argv[])


{
try{
try{
throw 12;
}catch(int){
cout << "No primeiro catch(){}, relancando a excecao. ";
throw;
}
}catch(int){
cout << "No segundo catch(){}";
}
return 0;
}
26

Apndice G Lista throw


//Apndice G - Lista throw
#include <iostream>
using namespace std;

void nova_un(){
cout << "Na nova unexpected, ";
throw;
}

void nova_ter(){
cout << "Na nova terminate, ";
}

void func()throw(bad_exception){
throw 1;
}

void func2()throw(int,char){
throw 1;
}

void func1()throw(){
throw 1;
}

int main(int argc, char *argv[])


{
//no C++ 11 pode-se fazer:
//set_terminate(nova_un);
//set_unexpected(get_terminate());
set_unexpected(nova_un);
set_terminate(nova_ter);

try{
func();
}catch(int){
cout << "int capturado, ";
}catch(bad_exception){
cout << "bad_exception capturado, ";
}

try{
func1();
27

}catch(int){
cout << "int capturado, ";
}catch(bad_exception){
cout << "bad_exception capturado, ";
}

try{
func2();
}catch(int){
cout << "int capturado, ";
}catch(bad_exception){
cout << "bad_exception capturado, ";
}

return 0;
}
28

Apndice H Apontadores Inteligentes


//Apndice H - Apontadores Inteligente
#include <iostream>
#include <memory>
using namespace std;

class nova{
int n;
public:
nova(int n){
this-> n = n;
cout << "Criando nova: " << n << ", ";
}
~nova(){cout << "Destruindo nova: " << n << ", ";}
};

int main(){
try{
nova n(1);
throw "opa";
}catch(...){cout << "Excecao capturada, ";}

try{
nova * d = new nova(2);
throw "opa";
delete d;
}catch(...){cout << "Excecao capturada, ";}

try{
auto_ptr<nova> m(new nova(3));
throw "opa";
}catch(...){cout << "Excecao capturada, ";}
}
29

Apndice I Excees de Entrada


//Exemplo 07 - Excees de entrada
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;

int main(int argc, char *argv[])


{
//utilizando a mscara de exceo
cin.exceptions(ios_base::failbit);

int i;
try{
while(2){
//o programa pede a entrada de um inteiro
cout << "Digite um inteiro" << endl;
cin >> i;
cout << i << endl << endl;
//caso seja inserido um tipo diferente de inteiro
//uma exceo do tipo ios_base::failure lanada
}
}
catch(ios_base::failure &erro){
cout << "Erro: Entrada incorreta: " << erro.what();
fflush(stdin);
}
return 0;
}

Anda mungkin juga menyukai