How to implement a singleton class in Symbian OS

<script language="javascript1.2" type="text/javascript"> </script>

How to implement a singleton class in Symbian OS        ID: TTS000222

Version 1.1
Published at www.forum.nokia.com on October 19, 2006.

Overview

The singleton pattern is one of the best-known patterns in software engineering. Essentially, a singleton is a class which only allows a single instance of itself to be created, and usually gives simple access to that instance.

How to use thread local storage (TLS) to implement a singleton class

In Symbian OS, each DLL that is loaded in each thread has a machine word of thread-specific memory that can be written to and read — but no other static memory, which is why you can't have static class member variables. Since static class member variables are usually used to implement the singleton pattern, in Symbian OS we have to get around this, for instance by using TLS.

The following code demonstrates a singleton object whose NewL function uses TLS to test whether an object of its own type has been created. If it has, it simply returns the pointer stored in TLS, converted to its own type. If not, it instantiates an object of its own type, stores it in TLS, and then returns it.

Note that this assumes that no other class in the DLL that includes this class uses TLS. If this is not the case, you must write a singleton manager class, which uses TLS to store a pointer to a structure of pointers to all the singleton classes that the program needs.

Example 1: Singleton implementation based on TLS

  ==============

  CMySingleton.h

  ==============

 

  class CMySingleton : public CBase

      {

  public: // constructor and destructor

      static CMySingleton* NewL();

      virtual ~CMySingleton();

  private: // constructors

      CMySingleton(); // private because of the singleton pattern; it is

                      // guaranteed that only NewL will call it

      void ConstructL();

  public: // other functions

      ...

  private: // other functions

      ...

  private: // data

      ...

      }

 

  ================

  CMySingleton.cpp

  ================

 

  CMySingleton::CMySingleton* NewL()

      {

      CMySingleton* singleton;

      // Check thread local storage:

      if ( Dll::Tls() == NULL )

          {

          // TLS is still null, which means that no CMySingleton has

          // been instantiated yet.  Do so now, and return that

          // instance:

          singleton = new ( ELeave ) CMySingleton();

          CleanupStack::PushL( singleton );

          singleton->ConstructL();

          CleanupStack::Pop( singleton );

          // Store a pointer to the new instance in thread local storage:

          TInt err = Dll::SetTls( static_cast<TAny*>( singleton ) );

          if ( err == KErrNone )

              {

              return singleton;

              }

          else

              {

              delete instance;

              User::Leave( err );

              return NULL;

              }

          }

      else

          {

          // CMySingleton has been instantiated once already, so return

          // that instance:

          singleton = static_cast<CMySingleton*>( Dll::Tls() );

          return singleton;

          }

      }

 

TLS on S60 3rd Edition

Since applications from S60 3rd Edition onwards are implemented as EXE programs, Dll::Tls() is not available anymore. Instead, TLS functionality is implemented in UserSvr class (e32svr.h):

static TInt DllSetTls(TInt aHandle, TAny *aPtr);

static TAny *DllTls(TInt aHandle);

static void DllFreeTls(TInt aHandle);

Note that EXE programs can contain writeable static data, but this is not recommended to be used except as a last resort.

Using class CCoeStatic to implement a singleton class

A simpler way of implementing singletons than using TLS is possible for those classes which use the CCoeEnv class. Since CCoeEnv is a part of the UI control framework, this concerns only applications, not application engines.

This applies also to S60 3rd Edition and later editions.

Example 2: Singleton implementation based on CCoeStatic

  ==============

  CMySingleton.h

  ==============

 

  /**

   * Example implementation of a singleton class by means of inheriting

   * from CCoeStatic.

   */

  class CMySingleton : public CCoeStatic

      {

 

  public: // constructors and destructor   

 

      /**   

       * Returns an instance of this class. When called for the first

       * time, a new instance is created and returned.  After that,

       * calling InstanceL returns the same instance that was created

       * earlier.

       *  

       * @return A pointer to a CMySingleton object   

       */   

      static CMySingleton* InstanceL();   

 

  private: // constructor

 

      /**   

       * Default constructor is private because we are using the

       * singleton design pattern.

       */   

      CMySingleton();   

 

      ...

 

      }

 

 

  ================

  CMySingleton.cpp

  ================

 

  // -------------------------------------------------------------------------

  // CMySingleton::CMySingleton

  // C++ default constructor. It is private because we are using the

  // singleton design pattern.

  // -------------------------------------------------------------------------

  CMySingleton::CMySingleton()

      : CCoeStatic( KUidMySingleton )

      {

      }

 

  // -------------------------------------------------------------------------

  // CMySingleton::InstanceL

  // Returns an instance of this class. When called for the first time,

  // a new instance is created and returned.  After that, calling

  // InstanceL returns the same instance that was created earlier.

  // Note that the UID passed to CCoeEnv::Static needs to be unique.

  // -------------------------------------------------------------------------

  CMySingleton* CMySingleton::InstanceL()

      {

      CMySingleton* instance = static_cast<CMySingleton*>

          ( CCoeEnv::Static( KUidMySingleton ) );

      if ( !instance )

          {

          instance = new ( ELeave ) CMySingleton;

          CleanupStack::PushL( instance );

          instance->ConstructL();

          CleanupStack::Pop();

          }

      return instance;

     }

 

<script language="javascript1.2" type="text/javascript"> </script> 转载自:http://www.forum.nokia.com/document/Forum_Nokia_Technical_Library/contents/FNTL/How_to_implement_a_singleton_class_in_Symbian_OS.htm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值