singleton template as base class in C++ [closed]
Asked Answered
M

2

11

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;}
};
Modest answered 26/12, 2016 at 7:44 Comment(6)
Might want to read gameprogrammingpatterns.com/singleton.html - don't use singletons if you can avoid it!Wellread
@Danh Just the typing?Modest
@saeidzamani It's necessary. It would access the Logger(){} and Logger(){}is privateModest
@Modest You are right. i delete my comment.Harrell
How is it that nobody voted which one is better as primarily opinion-based? Also, define correct. From the point of view of the language or the software design (that sounds as well primary opinion-based a question)?Spaghetti
@Spaghetti I also hope someone can answer From the point of view of the language or the software designModest
M
5
  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.

Magnificat answered 26/12, 2016 at 12:22 Comment(1)
@CinCout: Logger constructor/destructor are private. and getInstance use both. it can thank to friendship.Magnificat
H
1

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.

Harrell answered 26/12, 2016 at 8:12 Comment(6)
How derived from the template can be bad practice if the template is correct ? (look at protected section).Magnificat
@Magnificat Derived from the template class is not bad practice. adding unnecessary complexity is a bad practice.Harrell
@Magnificat I'm sorry that I just can not get your meaning.Is your meaning is make Singleton() {} and ~Singleton() {} private and use the first one?Modest
@Modest I think also it's better that make them private.Harrell
@saeidzamani cool! I just do this.Modest
@saeidzamani I used the second one.As Jarod42's said, after disallowing the copy constructor and adding basic getInstance,the singletonclass seems unneeded.Modest

© 2022 - 2024 — McMap. All rights reserved.