×
Namespaces

Variants
Actions
(Difference between revisions)

Abandonos (Leaves)

From Nokia Developer Wiki
Jump to: navigation, search
dcrocha (Talk | contribs)
cabezonxdg (Talk | contribs)
Line 1: Line 1:
 
Abandonos (Leaves) são utilizados ao invés do sistema tradicional de exceções do C++, a principal razão disso é pelo fato dos abandonos serem mais leves, necessitarem de menos linhas de códigos e também por não serem suportados pelo compilador GNU na época em que Symbian OS foi desenvolvido. Abandonos podem ocorrer como resultado de uma condição de erro ou de um evento anormal, como falta de memória ou de espaço em disco (ou falta de espaço no cartão de memória flash) para completar uma operação. O abandono propaga o erro a um local no código onde ele pode ser gerenciado, chamado TRAP harness.
 
Abandonos (Leaves) são utilizados ao invés do sistema tradicional de exceções do C++, a principal razão disso é pelo fato dos abandonos serem mais leves, necessitarem de menos linhas de códigos e também por não serem suportados pelo compilador GNU na época em que Symbian OS foi desenvolvido. Abandonos podem ocorrer como resultado de uma condição de erro ou de um evento anormal, como falta de memória ou de espaço em disco (ou falta de espaço no cartão de memória flash) para completar uma operação. O abandono propaga o erro a um local no código onde ele pode ser gerenciado, chamado TRAP harness.
 +
 +
<br>
 +
 +
== TRAP Harness ==
 +
 +
Para contornar a falta do sistema de exceção padrão foi desenvolvida a função TRAP e TRAPD que podem ser consideradas como alternativas ao Try/Catch. Ao ocorrer um abandono , este será propagado até que seja capturado por um TRAP. Caso não seja implementado pelo programador ele será capturado pelo TRAP do FrameWork e o SO irá tomar as precauções necessárias (Exibir uma dialog com o erro por exemplo)<br>
  
 
== Pilha de limpeza ==
 
== Pilha de limpeza ==
No entanto, devido a esse deslocamento, qualquer recurso local como memória alocada dinâmicamente terá sua referência perdida, podendo ocasionar uma brecha na memória. Por isso, programadores trabalhando com Symbian OS utilizam a pilha de limpeza (Cleanup Stack) para manter-se a par dos recursos gerênciados. Na ocorrência de um abandono, a pilha de limpeza irá destruir os recursos do elemento que está em seu topo.
+
 
 +
Considere o seguinte código:<br>
 +
 
 +
<br>
 +
<code cpp="cpp">void CMinhaClasse::CarregarAlgoL()
 +
{
 +
        CCarro* fiat = new (ELeave) CCarro();
 +
        fiat->DirigirL();
 +
        delete fiat;
 +
}
 +
</code>
 +
 
 +
 
 +
<br> <br> É feita a alocação dinâmica de um objeto do tipo CCarro e então este objeto chama o método DirigirL. Este método pode lançar uma exceção - ''Métodos que possam lançar exceção terminam com L'' - , caso uma exceção ocorra todas as variáveis automáticas do método CarregarAlgoL serão removidas incluindo neste caso o ponteiro fiat. Isto acontecendo perderemos a referência para a memória que fiat aponta - ''quando ocorre uma exceção não há garantia que o destrutor da classe será chamado ou que os códigos seguintes serão executados''-&nbsp; no exemplo, o comando delete nunca será executado. O resultado seria um vazamento de memória. Pode parecer que alguns bytes não representam muita coisa, mas para um sistema com recursos limitados e que não faz re-boot frequentemente isto pode ocasionar sérios problemas.<br>
 +
 
 +
Para resolver problemas como este foi desenvolvido o mecanismo de limpeza da pilha ( CleanupStack ). Considere o seguinte código:<br>
 +
 
 +
<br>
 +
<code cpp="cpp">void CMinhaClasse::CarregarAlgoL()<br>{<br> CCarro* fiat = new (ELeave) CCarro();<br> CleanupStack::PushL( fiat );<br> fiat->DirigirL();<br> CleanupStack::PopAndDestroy();<br>}</code>
 +
<br>Caso não tenha notado, foram adicionadas duas linhas de código que representam chamadas à métodos de CleanupStack. Neste código, caso DirigirL abandone não perderemos a referência a memória que fiat aponta. Seu uso é bastante simples, você adiciona ponteiros automáticos à pilha e na ocorrência de um abandono será chamado o destrutor do objeto que este ponteiro aponta e então sua memória será liberada através do operador User::Free.
 +
 
 +
 
 +
 
 +
<br>
 +
 
 +
<br>
 +
 
 +
A classe CleanupStack possui apenas&nbsp; 4 métodos (com suas devidas sobrecargas) todos são estáticos e bastante intuítivos.<br>
 +
 
 +
'''PushL'''- Adiciona um ponteiro a pilha de limpeza.
 +
 
 +
'''Pop'''- Remove um ponteiro da pilha de limpeza
 +
 
 +
'''PopAndDestroy'''- Remove um ponteiro da pilha de limpeza e libera sua memória. O mesmo que realizar um CleanupStack::Pop() e então delete.
 +
 
 +
<br>
 +
 
 +
'''''Nota 1''''': PushL pode gerar um abandono mas está fora do escopo deste artigo discutir isto, para maior informações consulte [1].
 +
 
 +
'''''Nota 2''''': Atributos membros de classe não devem ser adicionados a pilha de limpeza pois é função da sua classe realizar a deleção. Sendo colocado na pilha de limpeza poderia ocorrer uma dupla deleção o que pode ocasionar problemas.
  
 
== Construção em duas fases ==
 
== Construção em duas fases ==
Line 10: Line 55:
 
Exemplo:
 
Exemplo:
  
<code cpp>
+
<br>
 
+
<code cpp="cpp">void CMinhaAplicao::ConstructL(const TRect& aRect)
void CMinhaAplicao::ConstructL(const TRect& aRect)
+
 
{
 
{
 
     CMinhaAplicacao* self = CMinhaAplicacao(aRect);
 
     CMinhaAplicacao* self = CMinhaAplicacao(aRect);
Line 25: Line 69:
 
     iVariavel = 1;
 
     iVariavel = 1;
 
}
 
}
</code>
+
</code>
 +
 
 +
 
 +
<br> <br> <br>
  
 
== Leitura complementar ==
 
== Leitura complementar ==
  
[[Pilha de limpeza - Cleanup Stack]]<br>
+
[[Pilha de limpeza - Cleanup Stack|[1] - Pilha de limpeza - Cleanup Stack]]<br> [[Construtor em 2 fases]]<br> [[Gerência de memória]]<br>
[[Construtor em 2 fases]]<br>
+
[[Gerência de memória]]<br>
+
  
[[Category:Lang-PT]]
+
[[Category:Lang-PT]] [[Category:Symbian_C++_(Português)]]
[[Category:Symbian C++ (Português)]]
+

Revision as of 05:26, 20 December 2007

Abandonos (Leaves) são utilizados ao invés do sistema tradicional de exceções do C++, a principal razão disso é pelo fato dos abandonos serem mais leves, necessitarem de menos linhas de códigos e também por não serem suportados pelo compilador GNU na época em que Symbian OS foi desenvolvido. Abandonos podem ocorrer como resultado de uma condição de erro ou de um evento anormal, como falta de memória ou de espaço em disco (ou falta de espaço no cartão de memória flash) para completar uma operação. O abandono propaga o erro a um local no código onde ele pode ser gerenciado, chamado TRAP harness.


Contents

TRAP Harness

Para contornar a falta do sistema de exceção padrão foi desenvolvida a função TRAP e TRAPD que podem ser consideradas como alternativas ao Try/Catch. Ao ocorrer um abandono , este será propagado até que seja capturado por um TRAP. Caso não seja implementado pelo programador ele será capturado pelo TRAP do FrameWork e o SO irá tomar as precauções necessárias (Exibir uma dialog com o erro por exemplo)

Pilha de limpeza

Considere o seguinte código:


void CMinhaClasse::CarregarAlgoL()
{
CCarro* fiat = new (ELeave) CCarro();
fiat->DirigirL();
delete fiat;
}




É feita a alocação dinâmica de um objeto do tipo CCarro e então este objeto chama o método DirigirL. Este método pode lançar uma exceção - Métodos que possam lançar exceção terminam com L - , caso uma exceção ocorra todas as variáveis automáticas do método CarregarAlgoL serão removidas incluindo neste caso o ponteiro fiat. Isto acontecendo perderemos a referência para a memória que fiat aponta - quando ocorre uma exceção não há garantia que o destrutor da classe será chamado ou que os códigos seguintes serão executados-  no exemplo, o comando delete nunca será executado. O resultado seria um vazamento de memória. Pode parecer que alguns bytes não representam muita coisa, mas para um sistema com recursos limitados e que não faz re-boot frequentemente isto pode ocasionar sérios problemas.

Para resolver problemas como este foi desenvolvido o mecanismo de limpeza da pilha ( CleanupStack ). Considere o seguinte código:


void CMinhaClasse::CarregarAlgoL()<br>{<br> CCarro* fiat = new (ELeave) CCarro();<br> CleanupStack::PushL( fiat );<br> fiat->DirigirL();<br> CleanupStack::PopAndDestroy();<br>}


Caso não tenha notado, foram adicionadas duas linhas de código que representam chamadas à métodos de CleanupStack. Neste código, caso DirigirL abandone não perderemos a referência a memória que fiat aponta. Seu uso é bastante simples, você adiciona ponteiros automáticos à pilha e na ocorrência de um abandono será chamado o destrutor do objeto que este ponteiro aponta e então sua memória será liberada através do operador User::Free.




A classe CleanupStack possui apenas  4 métodos (com suas devidas sobrecargas) todos são estáticos e bastante intuítivos.

PushL- Adiciona um ponteiro a pilha de limpeza.

Pop- Remove um ponteiro da pilha de limpeza

PopAndDestroy- Remove um ponteiro da pilha de limpeza e libera sua memória. O mesmo que realizar um CleanupStack::Pop() e então delete.


Nota 1: PushL pode gerar um abandono mas está fora do escopo deste artigo discutir isto, para maior informações consulte [1].

Nota 2: Atributos membros de classe não devem ser adicionados a pilha de limpeza pois é função da sua classe realizar a deleção. Sendo colocado na pilha de limpeza poderia ocorrer uma dupla deleção o que pode ocasionar problemas.

Construção em duas fases

Construtores e destrutores não podem retornar um valor e por isso não pode abandonar. Pensando nisso, foi desenvolvido a contrução em duas fases para evitar que construtores gerem abandonos. Funções que possam gerar um abandono devem ser chamadas no ConstructL (L no final é uma convenção de nome que significa que essa função pode abandonar) ao invés do construtor padrão C++. Qualquer outra inicialização que não possa abandonar pode ser inicializada normalmente no construtor padrão.

Exemplo:


void CMinhaAplicao::ConstructL(const TRect& aRect)
{
CMinhaAplicacao* self = CMinhaAplicacao(aRect);
CleanupStack::PushL(self);
self->ConstructL(aRect) ;
CleanupStack::Pop(self);
return self;
}
 
CMinhaAplicacao::CMinhaAplicacao()
{
iVariavel = 1;
}





Leitura complementar

[1] - Pilha de limpeza - Cleanup Stack
Construtor em 2 fases
Gerência de memória

137 page views in the last 30 days.
×