Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo explica a necessidade e o método de liberação de objetos quando ocorre uma exceção. Os tópicos incluem:
As exceções geradas pela estrutura ou pelo aplicativo interrompem o fluxo normal do programa. Portanto, é muito importante acompanhar de perto os objetos para que você possa descartá-los corretamente caso uma exceção seja lançada.
Há dois métodos primários para fazer isso.
Manipule as exceções localmente usando as
trypalavras-chave ecatch, em seguida, destrua todos os objetos com uma instrução.Destrua qualquer objeto no
catchbloco antes de lançar a exceção fora do bloco para tratamento adicional.
Essas duas abordagens são ilustradas abaixo como soluções para o seguinte exemplo problemático:
void SomeFunc() // Problematic code
{
CPerson* myPerson = new CPerson;
// Do something that might throw an exception.
myPerson->SomeFunc();
// Now destroy the object before exiting.
// If SomeFunc above throws an exception this code will
// not be reached and myPerson will not be deleted.
delete myPerson;
}
Conforme escrito acima, myPerson não será excluído se uma exceção for gerada por SomeFunc. A execução salta diretamente para o próximo manipulador de exceção externa, ignorando a saída da função normal e o código que exclui o objeto. O ponteiro para o objeto sai do escopo quando a exceção deixa a função e a memória ocupada pelo objeto nunca será recuperada, desde que o programa esteja em execução. Isso é um vazamento de memória; ele seria detectado usando o diagnóstico de memória.
Manipulando a exceção localmente
O paradigma try/catch fornece um método de programação defensiva para evitar vazamentos de memória e garantir que seus objetos sejam destruídos quando ocorrerem exceções. Por exemplo, o exemplo mostrado anteriormente neste artigo pode ser reescrito da seguinte maneira:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
// Handle the exception locally
e->Delete();
}
// Now destroy the object before exiting.
delete myPerson;
}
Este novo exemplo configura um manipulador de exceção para capturar a exceção e tratá-la localmente. Em seguida, ele sai da função normalmente e destrói o objeto. O aspecto importante deste exemplo é que um contexto para capturar a exceção é estabelecido com os blocos try/catch . Sem um quadro de exceção local, a função nunca saberia que uma exceção havia sido lançada e não teria a chance de sair normalmente e destruir o objeto.
Lançando exceções após destruir objetos
Outra maneira de lidar com exceções é passá-las para o próximo contexto externo de tratamento de exceções. Em seu catch bloco, você pode fazer alguma limpeza de seus objetos alocados localmente e, em seguida, gerar a exceção para processamento adicional.
A função de lançamento pode ou não precisar desalocar objetos heap. Se a função sempre desalocar o objeto heap antes de retornar no caso normal, a função também deverá desalocar o objeto heap antes de lançar a exceção. Por outro lado, se a função normalmente não desalocar o objeto antes de retornar no caso normal, você deverá decidir caso a caso se o objeto heap deve ser desalocado.
O exemplo a seguir mostra como os objetos alocados localmente podem ser limpos:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
e->ReportError();
// Destroy the object before passing exception on.
delete myPerson;
// Throw the exception to the next handler.
throw;
}
// On normal exits, destroy the object.
delete myPerson;
}
O mecanismo de exceção desaloca automaticamente objetos de quadro; o destruidor do objeto de quadro também é chamado.
Se você chamar funções que podem gerar exceções, poderá usar blocos try/catch para garantir que você capture as exceções e tenha a chance de destruir todos os objetos criados. Em particular, lembre-se de que muitas funções MFC podem gerar exceções.
Para obter mais informações, consulte Exceções: Capturando e excluindo exceções.