Hoje deparei-me com um problema no projecto que estou a desenvolver no trabalho.
Andei a fazer umas alterações bem grandes e, por qualquer motivo, o construtor de um dos objectos envolvidos, está a “atirar” uma excepção (estas expressões ficam excelentes em Português :) ).
É um objecto algo complexo… talvez até demais, pois envolve heranças, polimorfismo, templates, fábricas abstractas (Abstract Factory design pattern… acho que tentar traduzir estas coisas não resulta lá muito bem) e tem vários membros que são objectos tão ou mais complexos ainda (utilizo a Boost extensivamente, por exemplo).
Após umas alterações radicais à referida classe (e não, não estou a usar Unit testing - ainda… eu sei, eu sei…), o construtor deixou de funcionar e estava a atirar a tal excepção - na lista de inicializadores.
Curiosamente, nunca me tinha deparado com uma excepção neste ponto do código e por isso não sabia como capturar e tratar uma excepção ocorrida aqui.
Felizmente o Google continua a ser amigo e rapidamente me encontrou a solução, no site do link anterior: http://www.cprogramming.com/tutorial/initialization-lists-c++.html (quase no fim da página, “Initialization Lists and Exceptions”)
A sintaxe é um pouco estranha mas nada de complicado: o ’try’ fica depois do construtor e antes dos dois pontos da lista de inicialização, e o ‘catch’ fica depois do corpo da função.
Um pormenor importante é que mesmo que tratemos a excepção, esta será lançada novamente, porque não é garantido que o objecto esteja num estado válido, dado que um dos seus membros ou partes da sua classe mãe, não puderam ser inicializados.
Aqui fica um exemplo:
class Foo
{
Foo() try : mStr("Um texto qualquer")
{
}
catch (...)
{
std::cerr << "Erro ao criar mStr";
// a excepção é novamente lançada aqui, como se cá estivesse um 'throw'
}
};
Isto fica aqui para me servir de auxiliar de memória e pode ser que seja útil a mais alguém, caso se deparem com uma situação idêntica.
Raúl Santos