C++ Singleton

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • hype261
    New Member
    • Apr 2010
    • 207

    C++ Singleton

    This is a question that I have had for a while, but never got around to understanding why and just followed suite. Hopefully you guys can answer my question.

    In C++ when creating a singleton people traditionally mark the default constructor, copy constructor, and assignment operator as private to ensure only one object of the class can be created/retrieved through a static method.

    I understand why the default constructor and copy constructor are marked as private, but what about the assignment operator?

    Maybe I am missing something, but I can't think of a way to create an object just using the assignment operator.

    I would like to say this isn't a question about the benefits and problems associated with Singletons in an application. I understand this.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Force of habit/best practice.

    If you create a copy constructor then best practice dictates that you create an assignment operator. However it is of no use in a singleton since, as you say, you can't construct an object to use the assignment operator on so it is made private to hide it away.

    I suspect in C++0x where I believe there is a syntax to say don't create a copy constructor and don't create an assignment operator that you will find singletons just don't have these members.

    Comment

    • hype261
      New Member
      • Apr 2010
      • 207

      #3
      C++ 0x

      I believe the new standard will allow this format for marking constructors and assignment operators.

      class NonCopyable
      {
      NonCopyable & operator=(const NonCopyable&) = delete;
      NonCopyable(con st NonCopyable&) = delete;
      NonCopyable() = default;
      };

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        You do not make constrcutors private to limit the number of objects.

        Read the article on the Singleton design pattern in the C/C++ Insights.

        Assuming you read the article, it says a singleton is a single object with a global point of reference.

        You can use a global Singleton* set to zero when the program loads. The Singleton constrcutor creates an object on the heap only if the global pointer is zero. When it does, it puts the address of this object into that global pointer and that shuts off creating more objects.

        The other thing you can do is create singleton objects as global objects and use the constructor to add the objects to a registry so you cna ask for the objecty by name later on.

        Nowhere do you make constructors private.

        The only practical ise for a private constrcutor is to prevent that constructor from being called at all. Like a private default constructor to prevent objects from being created with no arguments.

        Comment

        • hype261
          New Member
          • Apr 2010
          • 207

          #5
          Originally posted by weaknessforcats
          You do not make constrcutors private to limit the number of objects.

          Read the article on the Singleton design pattern in the C/C++ Insights.

          Assuming you read the article, it says a singleton is a single object with a global point of reference.

          You can use a global Singleton* set to zero when the program loads. The Singleton constrcutor creates an object on the heap only if the global pointer is zero. When it does, it puts the address of this object into that global pointer and that shuts off creating more objects.

          The other thing you can do is create singleton objects as global objects and use the constructor to add the objects to a registry so you cna ask for the objecty by name later on.

          Nowhere do you make constructors private.

          The only practical ise for a private constrcutor is to prevent that constructor from being called at all. Like a private default constructor to prevent objects from being created with no arguments.
          WeaknessforCats ,

          I read the article that you put down and even in the article itself it makes the default constructor protected for the following reason.

          The default constructor is protected so only a derived class can execute it. This makes it possible to create an instance of the derived class but not an instance of the SysParms class itself.

          If you don't intend to make the Singleton class a part of a class hierarchy then a private constructor is a resonable thing to do.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            It's true even in the example the constructor is protected. What is public is the static function that returns a reference to the instance (allocating if required) of the object.

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              If you don't intend to make the Singleton class a part of a class hierarchy then a private constructor is a resonable thing to do.
              If a constructior is private, then how can you call it to build your object?

              A private constructor means that your objects are not be constructed using that constructor.

              Comment

              • hype261
                New Member
                • Apr 2010
                • 207

                #8
                Originally posted by weaknessforcats
                If a constructior is private, then how can you call it to build your object?

                A private constructor means that your objects are not be constructed using that constructor.
                Weaknessforcats ,

                Hopefully this code example will clear the confusion up for you.

                Singleton.h

                Code:
                #ifndef SINGLETON_H
                #define SINGLETON_H
                
                
                class Singleton
                {
                public:
                	
                	static Singleton * getInstance();
                
                	static void releaseInstance();
                
                	void printMe() const;
                
                private:
                	Singleton(){};
                
                	Singleton(const Singleton & instance);
                
                	Singleton& operator=(const Singleton & instance);
                
                
                	static Singleton * instance_;
                
                
                };
                
                #endif
                Singleton.cpp

                Code:
                #include "Singleton.h"
                #include <iostream>
                
                Singleton * Singleton::instance_ = 0;
                
                Singleton * Singleton::getInstance()
                {
                	if(!instance_)
                		instance_ = new Singleton();
                
                	return instance_;
                }
                
                
                void Singleton::releaseInstance()
                {
                
                	delete instance_;
                
                	instance_ = 0;
                }
                
                
                void Singleton::printMe() const
                {
                
                	std::cout << "Hey I am a Singleton with the address of " << instance_ << std::endl;
                }
                main.cpp

                Code:
                #include "Singleton.h"
                
                int main()
                {
                
                	Singleton::getInstance()->printMe();
                	
                	Singleton::getInstance()->printMe();
                
                	Singleton::releaseInstance();
                
                	return 0;
                }
                As you can see I am using the private constructor to build the singleton in the static method getInstance if it already hasn't been initialized.

                Output on my system:

                Hey I am a Singleton with the address of 006C78E0
                Hey I am a Singleton with the address of 006C78E0

                Comment

                Working...