• Nenhum resultado encontrado

Controlo de Excepções

N/A
N/A
Protected

Academic year: 2023

Share "Controlo de Excepções"

Copied!
17
0
0

Texto

(1)

Controlo de Excepções

(2)

void f(X&){}

void ff(void) { X x;

cout << "f (call)" << endl;

f(x);

cout << "f (return)" << endl;

}

class X {

public:

X(const X&) { cout << "copy constructor\n"; } X() { cout << "constructor\n"; }

virtual ~X() { cout << ”destructor\n"; } };

constructor f (call)

f (return) destructor

(3)

void ff(void) { X x;

cout << "before throw" << endl;

throw x;

cout << "after throw" << endl;

}

void fff(void) {

try {

ff();

}

catch(...) { cout << "catch\n"; } }

int main(int argc, char* argv[]) { fff();

return 0; }

constructor before throw

copy constructor destructor

catch

destructor

(4)

void ff(void) { X x;

cout << "before throw" << endl;

throw x;

cout << "after throw" << endl;

}

void fff(void) {

try {

ff();

}

catch(...) { cout << "catch\n"; } }

int main(int argc, char* argv[]) { fff();

return 0; }

constructor before throw destructor catch

throw &x;

(5)

void ff(void) { X x;

cout << "before throw" << endl;

throw x;

cout << "after throw" << endl;

}

void fff(void) {

try {

ff();

}

catch(...) { cout << "catch\n"; } }

int main(int argc, char* argv[]) { fff();

return 0; }

constructor before throw

copy constructor copy constructor destructor

catch

destructor destructor catch(X x)

(6)

void ff(void) { X x;

cout << "before throw" << endl;

throw x;

cout << "after throw" << endl;

}

void fff(void) {

try {

ff();

}

catch(...) { cout << "catch\n"; } }

int main(int argc, char* argv[]) { fff();

return 0; }

constructor before throw destructor catch

throw &x;

catch(X* x) static X x;

(7)

void ff(void) { X x;

cout << "before throw" << endl;

throw x;

cout << "after throw" << endl;

}

void fff(void) {

try {

ff();

}

catch(...) { cout << "catch\n"; } }

int main(int argc, char* argv[]) { fff();

return 0; }

constructor before throw

copy constructor destructor

catch

destructor catch(X& x)

static X x;

slicing problem

(8)

class X{ ... };

void f()

{ static X x;

...

throw &x; //ponteiro }

void ff()

{ try { f(); }

catch(X *x) { ... } // ponteiro }

// global

(9)

class X {

public: vitrual void f() throw(); };

class Y : public X { ... };

class Z : public Y {

public: vitrual void f() throw();

. . . . };

void ff()

{ . . . . if( ... ) throw Z();

}

void fff() {

try { ff(); }

catch (X x) { cerr << x.f(); }

} // chama X::f(), nunca Z::f()

slicing problem

(10)

slicing problem static X x;

void ff()

{ ...

if( ... ) throw Z();

}

void fff() {

try { ff(); }

catch (X& x) { cerr << x.f(); }

} // agora chama Z::f()

(11)

void f(int i) {

try {

if( . . . ) throw i;

} }

catch(float f) {

. . . . }

}

(12)

extern void f();

void ff() throw (int);

void ff() throw();

Por defeito a função unexpected chama a função terminate.

Podemos redefinir estas funções usando funções da biblioteca tais como set_terminate e set_unexpected.

void f() throw(X,Y) { ... } - específica a lista (X,Y) das excepções que podem ser geradas pela função f. Se a função f gerar outras excepções (que não são X nem Y), a função especial que se chama unexpected vai ser chamada automaticamente.

A função terminate é chamada nas seguintes ocasiões:

1. É impossível encontrar o respectivo bloco catch.

2. Existem erros na pilha.

3. Existem erros no destrutor que destroí os objectos automáticos (locais).

(13)

Sumário de excepções

1. O mecanismo de controlo de excepções permite interromper o programa em pontos onde aparece uma situação anormal. Mais frequentemente este mecanismo é usado para procurar os erros.

2. Quando o programa é interrompido o controlo, e possivelmente os dados ,vão ser passados do ponto de execução ao ponto de um programa predefinido onde a excepção vai ser tratada.

3. Este mecanismo pode ser usado só para as excepções

sincronizadas. Isto significa que estas excepções só podem ser

geradas dentro do programa. Por exemplo, não é possível considerar excepções que vão ser geradas ao pressionar as teclas Ctrl-C.

4. Para o controlo das excepções a linguagem C++ introduz três novas palavras chaves que são throw, try e catch.

5. As excepções podem ser de qualquer tipo mas mais frequentemente têm o tipo class ou struct.

(14)

6. O bloco do código que pode ter excepções deve estar delimitado pela palavra chave try e parêntesis ( {} ). Depois do bloco

try deve seguir pelo menos um bloco catch que se chama o manipulador da excepção. Este bloco também deve estar em parêntesis ( {} ).

É permitido usar vários blocos catch após do bloco try.

7. A excepção é gerada quando a instrução throw é activada. Neste caso as seguintes acções vão ser executadas:

7.1. Procuramos o respectivo manipulador, i.e. o primeiro bloco catch que tem o argumento associado com a instrução throw.

7.2. Se o manipulador for encontrado começamos o processo que se chama “stack unwinding”. Isto significa que todos os destrutores para os objectos locais construídos a partir do ínicio do bloco catch vão ser invocados. De notar que os destrutores vão ser chamados só para os objectos que foram construídos completamente.

7.3. O controlo vai ser passado ao manipulador que foi encontrado.

(15)

8. A instrução throw passa o controlo ao primeiro bloco

catch, i.e. ao manipulador cujo bloco try está a ser executado.

9. A palavra chave throw pode ser usada das seguintes formas:

9.1. throw operand; - activa o indicador (operador) da excepção, que vai ser passado ao respectivo manipulador.

9.2. throw ; - activa novamente a mesma excepção.

9.3. void f() throw(X,Y) { ... } - específica a lista (X,Y) das excepções que podem ser geradas pela função f. Se a função f gerar outras excepções (que não são X nem Y), a função especial que se chama unexpected vai ser chamada automaticamente.

10. A lista das excepções não faz parte da função. Para esta lista existem os seguintes convénios:

10.1. A função sem a lista pode gerar qualquer excepção.

10.2. A função com a lista vazia tal como throw() não pode gerar qualquer excepção.

10.3. A função que pode gerar a excepção do tipo (da classe) X pode também gerar qualquer excepção da classe Y (XY) se a classe

base X tiver o atributo público, por exemplo class Y : public X {...};

(16)

11. O manipulador das excepções pode ser apresentado das duas seguintes formas:

try { ... }

A: catch(Type Object) { ... } B: catch(...) { ... }

O tipo do argumento Object pode ser: Type, Type&, const Type, const Type&. O argumento é aceite se pelo menos uma das

seguintes regras for válida:

a) o Objecto tem o tipo Type.

b) Type é um tipo da classe base para o Objecto (que pode ser aceite).

c) Type é um ponteiro e o Objecto tem o tipo ponteiro que

pode ser convertido ao Type através de uso das regras da linguagem.

12. O manipulador catch(...) trata qualquer excepção independente do seu tipo.

13. A procura nos blocos catch é feita pela sequência em que estes blocos se encontram no programa.

(17)

14. Vamos assumir que temos a classe Base e a classe Derivada

(Base  Derivada). Neste caso, se a classe Base for encontrada antes da classe Derivada vamos ter um erro porque a classe Derivada

nunca vai ser executada.

15. O manipulador catch(...) deve ser sempre o último bloco na lista dos blocos catch.

16. Depois de terminar o bloco catch o controlo vai ser passado ao fim da lista que contém todos os blocos catch e depois para o bloco try.

17. Para sair dos blocos catch ou try não é permitido usar a instrução goto.

18. A função terminate é chamada nas seguintes ocasiões:

18.1. É impossível encontrar o respectivo bloco catch.

18.2. Existem erros na pilha.

18.3. Existem erros no destrutor que destroí os objectos automáticos (locais).

19. Por defeito a função unexpected chama a função terminate.

Podemos redefinir estas funções usando funções da biblioteca tais como set_terminate e set_unexpected.

Referências

Documentos relacionados

Informações de qualidade de produto de mercado / Informações de qualidade de produção Controle de entrega Melhoria do desenho Produtos promocionais / informação Serviço

Das combinações mais marcantes e coloridas até as mais sóbrias, os acessórios vieram para enriquecer os guarda-roupas masculinos – e são a grande aposta.. Marcas masculinas

Era uma cena que me parecia tão artificial, porque minha cabeça não concebia o fato de Jean viver num ambiente tão agradável.. Nada parecia

Requereram a concessão de medida liminar para que, até o restabelecimento da capacidade de atendimento das redes pública e privada de saúde, seja  determinado ao

Com o intuito de estabelecer diretrizes para a implantação de uma nova aciaria, propõe-se a análise comparativa de aspectos técnicos e econômicos de três tipos de processos: Forno

O presente estudo objetivou testar a influência do guano na diversidade e abundância de invertebrados na caverna Toca da Raposa, município de Simão Dias,

As condições de preparo da MCM-41 influenciam na sua obtenção e entre os componentes utilizados para sua síntese está a sílica que geralmente provém de uma

Miris Human Milk Analyser, analisa a energia, gordura, carboidratos e proteína verdadeira do leite.. Excluindo componentes não proteícos, como uréia, o equipamento Miris