Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 11:30, 31 October 2007.

Utilizando classes Singleton em Symbian OS

From Forum Nokia Wiki

Sigleton é um padrão de projeto definido no livro Design Patterns: Elements of Reusable Object-Oriented Software. Esse padrão diz que para uma determinada classe apenas uma única instância deve existir por todo o programa.

Em C++ padrão a forma mais simples de se criar uma classe Singleton é utilizar um ponteiro estático e um método estático. Em Symbian OS isto funciona para EXE mas não para DLL*. Pois este ponteiro estático é considerado como um Writable Static Data (variável global que existe durante toda a vida do processo), e isto não é permitido para DLLs.

Para fazer a criação de singletons temos duas possibilidades, utilizar a classe base CCoeStatic, ou utilizar Thread Local Storage (TLS). Até o momento nunca utilizei TLS então irei focar na utilização da classe CCoeStatic. A principal desvantagem na utilização de CCoeStatic é que você não pode utilizá-lo em aplicações baseadas em console (sem interface gráfica).

A lógica utilizada será bem parecida com o singleton em C++ padrão, a diferença é que não iremos utilizar um ponteiro estático. Iremos precisar criar um UID único para a classe (único dentro da aplicação), ele será utilizado para identificar de qual classe iremos obter a instância, caso esteja trabalhando com várias classes Singleton.

ExemploSingleton.h

/*
* Exemplo de criação de classes Singleton utilizando CCoeStatic.
* Autor: s60brasil.blogspot.com
*/
 
#include // Cabeçalho de CCoeStatic.
 
class CExemploSingleton : public CCoeStatic
{
    public:
       /* Retorna uma instância desta classe.
        * Na primeira vez que este método for chamado ele fará a criação da  instância.
        * Em chamadas subsequentes será retornada esta instância.
        */
       static CExemploSingleton* InstanceL();
       ~CExemploSingleton();
    private:
       // Construtor precisa ser privado para evitar que outras classes a instancie diretamente.
       CExemploSingleton();
       // Construtor de segunda-fase caso precise realizar alguma operação que           possa abandonar
       void ConstructL();
};

ExemploSingleton.cpp

#include "ExemploSingleton.h"
 
/* UID definido para a classe CExemploSingleton.
 * Este UID precisa ser único para esta classe dentro da aplicação.
 */
const TUid KUidClasseSingleton = { 1 };
 
/* Construção da classe.
 * Passamos para CCoeStatic a UID da classe e prioridade de destruição da instância.
 */
CExemploSingleton::CExemploSingleton() : CCoeStatic( KUidClasseSingleton, EDefaultDestructionPriority )
{
 
}
 
CExemploSingleton::~CExemploSingleton()
{
     // Não implementado.
}
 
CExemploSingleton* CExemploSingleton::InstanceL()
{
     CExemploSingleton* instancia = static_cast
                 ( CCoeEnv::Static( KUidClasseSingleton ) );
     /* Somente entrará neste if na primeira chamada a InstanceL();
      * Chamadas subsequentes a este método retornarâo esta instância.
      */
     if( !instancia )
     {
         instancia = new (ELeave) CExemploSingleton();
         /* Adiciona o ponteiro ao CleanupStack para garatir que está referência  não será perdida caso ConstructL abandone.*/
         CleanupStack::PushL( instancia );
         // Chamada ao construtor de segunda-fase
         instacia->ConstructL();
         // Após chamar métodos que possam abandonar , liberar da pilha
         CleanupStack::Pop( instancia );
     }
 
     return instancia;
}
 
void CExemploSingleton::ConstructL();
{
     // Não implementado
}

O código por si só é bastante fácil de compreender. Como disse anteriormente basta fazer chamadas ao método InstanceL() para receber a referência da classe Singleton. Na primeira chamada será alocado o ponteiro e nas outras será apenas retornado a instância. Algo que vale ressaltar é a construção da classe:

CExemploSingleton::CExemploSingleton() : CCoeStatic( KUidClasseSingleton, EDefaultDestructionPriority )
{
 
}

Passamos através do contrutor para CCoeStatic dois argumentos. Uma das definições do construtor de CCoeStatic é:

CCoeStatic(TUid aUid, TInt aDestructionPriority, TScope aScope=EThread);

Onde:

aUid = Uid da classe singleton.
aDestructionPriority = Define com que prioridade a instância será destruída. Quanto maior este valor , mais cedo o objeto será destruído. Valores positivos fazem com que o objeto seja destruído antes de CCoeAppUi enquanto valores negativos fazem com que o objeto seja destruído após CCoeAppUi.
aScope = Define para quem o objeto estará acessível. Por definição é para a thread da aplicação.

---
(*) = A partir da versão 8.1, passou a ser possível utilizar dessa maneira.

Referência

Series60 Brasil Blog
SymbianOS SDK

Related Discussions
Thread Thread Starter Forum Replies Last Post
Panic when closing file djgtram General Symbian C++ 10 2006-01-27 09:58
some doubts regarding receiving faxces for a1000 Anjali Ram General Symbian C++ 2 2005-05-06 06:07
FileConnectionApi missing stuartdd Mobile Java Tools & SDKs 5 2005-06-17 03:06
What is the default classpath for the Nokia 9210 Communicator Java apps? nkn_motoko Mobile Java General 1 2001-11-06 20:55
Class not found errors BernWozny Mobile Java General 2 1970-01-01 02:00
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX