如何在C ++中实现Singleton

时间:2011-11-21 07:30:16

标签: c++ inheritance singleton

This post就是我刚刚读到的内容。

他在C ++中实现Singleton的方式让我很困惑。我有几个问题,这是他的代码:

template<typename T>
class Singleton {
public:
    static T& getInstance() {  //Question 1
        return instance;
    }
private:
    static T instance;
};

class DebugLog : public Singleton<DebugLog> {  //Question 2
public:
    void doNothing() {}
};

问题

  1. 我认为我们应该将static T& getInstance()的定义放在课堂体外,对吗?

  2. 他试图让class DebugLog成为单身类,但当他继承Singleton<DebugLog>时,DebugLog尚不存在,对吧?如果正确,那么模板类Singleton如何实例化一个不存在的类?

3 个答案:

答案 0 :(得分:5)

1)不,你如何构建代码并不重要。顺便说一下,Singleton不是一个类:它是一个模板。由于完整的模板定义无论如何都必须在任何实例化站点都可访问,因此您也可以内联定义所有内容。

2)class DebugLog : public Singleton<DebugLog>没问题。我们不是从一个不存在的类继承;相反,我们继承自班级Singleton<DebugLog>。模板可以在不完整的类型上实例化。 (对于这样的类型参数,您可以做什么和不能做什么规则。)

例如,template <typename T> class Foo { };当然可以在任何类型上实例化而没有问题。更有趣的是,template <typename T> struct PointerFactory { typedef T * type; };可以在任何类型上实例化,完整与否。在目前的情况下,CRTP中模板参数的目的仅仅是告知基类最终的派生类型,所以这完全没问题。

答案 1 :(得分:1)

  1. 如果在外面定义函数,那肯定会更清晰 该类,使代码更易于阅读和维护。在这 但是,完整的课程足够小,不同 并不是很好,当然,因为我们正在处理模板, 实际定义仍然必须包含在每个翻译单元中 使用它。
  2. C ++标准并没有提到关于类(或任何东西)的“存在” 其他)。在模板实例化时,查找名称查找 DebugLog,并发现它是一个类(因此是一个类型)。在那时候, 它是一种不完整的类型,你可以做的事情有限 不完整的类型。如果是实例化的类模板 不做任何需要完整类型的事情(Singleton 没有问题,那就没问题了。 (注意只有班级 定义在此时被实例化;类成员函数会 在使用它们之前不得实例化。)

    我可能会补充说,还有一件重要的事情遗漏了 您发布的代码:声明没有定义 Singleton::instance。您仍然需要添加:

    template<typename T> T Singleton<T>::instance;
    

    的某个地方。

答案 2 :(得分:-3)

在这种情况下,您必须使用指向T的指针:

template<typename T>
class Singleton {
public:
    static T& getInstance() {
        static T * instance = NULL;
        if (!instance)
            instance = new T;
        return *instance;
    }
};

class DebugLog : public Singleton<DebugLog> {  //Question 2
    public:
        void doNothing() {}
};