C++
  Home arrow C++ arrow Page 4 - C++ In Theory: The Singleton Pattern, Part...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

C++ In Theory: The Singleton Pattern, Part I
By: J. Nakamura
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 55
    2005-01-18

    Table of Contents:
  • C++ In Theory: The Singleton Pattern, Part I
  • A Logging Class
  • Statics are not Singletons
  • The Gamma Singleton
  • The Meyers Singleton

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    C++ In Theory: The Singleton Pattern, Part I - The Gamma Singleton


    (Page 4 of 5 )

    It is clear that singletons are not very flexible when we have to rely on static variables and functions. But I have digressed a little, so let's have a look at how the Log class would be implemented as a singleton in "Design Patterns" [Gamma].

    class Log {

    public:
      static Log* Instance() {
        if (!m_pInstance)
          m_pInstance = new Log;
        return m_pInstance;
    }
      void Write(char const *logline);
      bool SaveTo(char const *filename);
    private:
      Log();        // ctor is hidden
      Log(Log const&);    // copy ctor is hidden

      static Log* m_pInstance;
      static std::list<std::string> m_data;
    };

    // in log.cpp we have to add
    Log* Log::m_pInstance = NULL;

    The constructor and copy constructor are hidden because they are made private, so no user has access to them except for the class itself. The only way to instantiate a Log is by calling Instance() which checks whether or not this class has already been instantiated. This seems like the perfect way to restrict access to our class, and we are sure that only one is ever created during the lifetime of our application!

    “Seems?” I hear you think. If you look closely, you will notice that m_pInstance is never destructed. Depending on the definition you use for memory leakage, this class is actually leaking memory.

    Some consider a memory leak to be an accumulation of data, of which you lose the references (and thus the ability to free them) during runtime. In this case m_pInstance is holding on to the memory right up to the end of the application, so does not have to be considered a memory leak. Since most operating systems free the memory a process has been using when it terminates, m_pInstance can be considered not to be leaking.

    You should not depend on the operating system to clean up the memory you have allocated, especially not when your code has to be platform independent. There is at least one OS out there that doesn’t free the memory left allocated by a terminated process (I don't remember which one…most probably it is the OS/400) and if your singleton opened a file, socket or other system resources, these may remain locked after the process has closed and you will have created a resource leak.

    Maybe we should have coded our Log singleton this way:

    class Log {
    public:
      static Log* Instance() {
        return &m_pInstance;
    }
      void Write(char const *logline);
      bool SaveTo(char const *filename);
    private:
      Log();        // ctor is hidden
      Log(Log const&);    // copy ctor is hidden

      static Log m_pInstance;
      static std::list<std::string> m_data;
    };

    // in log.cpp we have to add
    Log Log::m_pInstance;

    This solution loses an important benefit that our previous singleton did have: dynamic initialization. It is useful for your application to only create the singleton when it is needed/called upon. With our polymorphic example, every class would be instantiated and we would have to instantiate all forms of logging (even when this might not be possible!), while only using one of them!

    Static initialization remains a problem as well. There is no guaranteed sequence in which statics are created and destroyed…which will cause problems for our logging class, but we will take a more detailed look at this later on.

    More C++ Articles
    More By J. Nakamura


       · The article isw very good for a beginner showing him how the solution...
       · class LogNetwork : public LogNetwork {};I don't think this is right.a class...
       · You are very right it should beclass LogNetwork : public LogBasethx for...
       · "...which can be written to a single file when Log::Write is called."That should...
       · You discussed using polymorphism to have different logging behaviors, and using the...
     

    C++ ARTICLES

    - Multiplying Large Numbers with Karatsuba`s A...
    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion
    - First Steps in (C) Programming, continued
    - First Steps in (C) Programming, introduction
    - C++ Preprocessor: Always Assert Your Code Is...
    - C++ Preprocessor: The Code in the Middle
    - Programming in C
    - Temporary Variables: Runtime rvalue Detection






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway
    Stay green...Green IT