1

I have been recently asked about singleton design pattern in c++. I didn't know exactly what it does or when it is required, so I tried googling it. I found a lot of answers primarily on stackoverlow but I had a hard time understanding the code mentioned in these questions and answers. I know following property that a singleton should satisfy, correct me if I am wrong.

It is used when we need to make one and only one instance of a class. 

This raises following question in my mind

Does this mean that it can be created only once or does this mean that it can be 
created many times but at a time only one copy can exist?

Now coming to the implementation. copied from here

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                              // Instantiated on first use.
            return instance;
        }
    private:
        S() {};                   // Constructor? (the {} brackets) are needed here.
        // Don't forget to declare these two. You want to make sure they
        // are inaccessible otherwise you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement
};

Please explain:

  1. Why do we have to make getinstace() function static?
  2. Why do we need S(S const&); constructor?
  3. What does void operator=(S const&); do?
  4. Why don't we implemented last two function?
  5. Why do we need the guaranteed destruction of this instance(as mentioned in the code)?
4

3 回答 3

3

1.Why do we have to make getinstace() function static?

This is the only way to get hold of an instance - static means you dont need an existing instance to call it. If you needed an instance to get an instance you'd be stuck in a chicken vs. egg situation.

That is since its static you can write:

S::getinstance().blah();

If it was not static you'd need to write

S& s_instance = .... 
s_instance.getInstance().blah();

But since you've already got an instance you dont need to call getInstance. And how did you get that instance if the only way to get an instance is through getInstance?

2.Why do we need S(S const&); constructor?

You don't. Its intentionally private and not implemented, so calling it will cause an error. If it were not explicitly made private and not implemented the compiler will create a default public copy constructor for you... This would mean people could write

S scopy(S::getInstance());

and they'd end up with a new instance of S - breaking singleton semantics.

3.What does void operator=(S const&); do?

Same as 2. Its not implemented and private, so calling it will cause an error. Again if you're not explicit about it the compiler will create a default one for you, in which case users could get a new instance via.

S scopy = S::getInstance();

4.Why don't we implemented last two function?

If you could copy/assign the singleton, it would lose its singleton status. Only one singleton should exist at any time.

Note however that singleton is often considered an anti-pattern. Something you dont want to use without a very good reason. And it's also wise to understand the threading issues that come with it... And then on top of that there's the static initialisation order fiasco that you run into with some ways of implementing it. (The way in your code is OK, but it's pretty easy to get wrong.)

于 2013-10-08T02:20:23.013 回答
1

1) Yes. This function lets you actually get at the one single instance of S. So you call S::getInstance(). If it's not static then you won't be able to do that.

2, 3 and 4) Notice that the constructors and operator= are private. That's to prevent someone from making another instance of S, thus invalidating the singleton status.

Instead of constructing your own S you're supposed to use S::getInstance() to get at the one single instance.

于 2013-10-08T02:15:46.813 回答
1
  1. Yes, it should be static, because it doesn't need an instance pointer. Making it non-static would be unproductive.

  2. Yes, we do need at least one functional constructor. The initial instance needs to be made somehow. When you create the first instance, a private constructor will force the external users to get the instance through getInstance.

  3. The assignment operator operator=(S const&) is used when you'd assign a new value to this instance. It makes no sense for a singleton, so is declared private and left without an implementation. Nobody can use it.

  4. No, the copy constructor and assignment operator need to be both private and without implementation. This is a C++ idiom that means: This class cannot be copied nor assigned to.

于 2013-10-08T02:15:54.663 回答