singleton template as base class in C++

14.1k views Asked by At

According to C++ Singleton design pattern I wrote a singleton template

template <typename T>
class Singleton
{
    public:
        static T& getInstance()
        {
            static T instance;
            return instance;
        }
    protected:
        Singleton() {}
        ~Singleton() {}
    public:
        Singleton(Singleton const &) = delete;
        Singleton& operator=(Singleton const &) = delete;
};

And then I wrote a Logger singleton(The first one)

class Logger                            // not derived Singleton<Logger>
{
    friend class Singleton<Logger>;
    private:
        Logger(){};
        ~Logger(){};                          
    public:
        void print(void){std::cout << "hello" << std::endl;}
};

int main(void)
{
    Singleton<Logger>::getInstance().print(); // use Singleton<Logger>
    return 0;
}

but I can also(The second one)

class Logger:public Singleton<Logger>    // derived Singleton<Logger>
{
    friend class Singleton<Logger>;
    private:
        Logger(){};
        ~Logger(){};                          
    public:
        void print(void){std::cout << "hello" << std::endl;}
};

int main(void)
{
    Logger::getInstance().print();      // use Logger
    return 0;
}

Then my questions are

  1. Is my singleton template correct?
  2. If singleton template is correct, the both Logger is correct?
  3. The difference between the first one and the second one,which one is better?

UPDATE
After the answers,I learned that the first one allows to have several logger and the singleton class seems unneeded.SO I discard the first one.
About the seconde one I omit the destructor and then complier would generate a default inline public one. That seems more concise and more efficient.

class Logger:public Singleton<Logger>    // derived Singleton<Logger>
{
    friend class Singleton<Logger>;
    private:
        Logger(){};                       
    public:
        void print(void){std::cout << "hello" << std::endl;}
};
2

There are 2 answers

1
Jarod42 On BEST ANSWER
  1. Is my singleton template correct?

Yes it is.

  1. If singleton template is correct, the both Logger is correct?

Your first snippet allows to have several logger thanks to copy constructor. So in this regard, it is incorrect.

  1. The difference between the first one and the second one, which one is better?

If you fix first snippet to disallow also copy constructor, then you miss only the basic getInstance and your Singleton class seems unneeded.

With second snippet, you may even omit the destructor.

6
saeid zamani On

1)Your singleton template is correct.

2)Your both logger is correct. but the second one is a bad practice. because it's not necessary that logger derived from singleton template. you can examine this by put this line in second one :

Singleton<Logger>::getInstance().print();

works fine.

3)the first one is better.