单例模板作为C ++中的基类

时间:2016-12-26 07:44:44

标签: c++ templates singleton derived

根据C++ Singleton design pattern我写了一个单身人士模板

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;
};

然后我写了一个Logger单例(第一个)

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;
}

但我也可以(第二个)

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;
}

然后我的问题是

  1. 我的单身人士模板是否正确?
  2. 如果单例模板正确,则两个Logger都正确吗?
  3. 第一个和第二个之间的区别,哪一个更好?
  4. 更新
    在答案之后,我了解到第一个允许有几个记录器并且singleton类似乎不需要。我丢弃第一个。
    关于seconde,我省略析构函数,然后编译器将生成默认的内联公共版本。这似乎更简洁,更有效。

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

2 个答案:

答案 0 :(得分:2)

  
      
  1. 我的单身人士模板是否正确?
  2.   

是的。

  
      
  1. 如果单例模板正确,则两个Logger都正确吗?
  2.   

由于复制构造函数,您的第一个代码段允许使用多个记录器。 所以在这方面,这是不正确的。

  
      
  1. 第一个和第二个之间的区别,哪一个更好?
  2.   

如果您修复第一个代码段以禁止复制构造函数,那么您只会错过基本的getInstance并且您的Singleton类似乎不需要。

使用第二个片段,您甚至可以省略析构函数。

答案 1 :(得分:0)

1)你的单身人士模板是正确的。

2)你的记录器都是正确的。但第二个是不好的做法。因为记录器不需要从单例模板派生。 您可以通过将此行放在第二行来检查这一点:

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

工作正常。

3)第一个更好。