如何在C++中实现Singleton
This post就是我刚才读的。如何在C++中实现Singleton
他在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() {}
};
问题
我想我们应该把
static T& getInstance()
的定义类主体以外的,对不对?他试图让
class DebugLog
成为一个单独的类,但是当他继承Singleton<DebugLog>
时,DebugLog
不存在了吧?如果对,那么模板类Singleton
如何实例化一个不存在的类?
- 这肯定会是更清洁,如果函数是的 定义在类外,使代码更容易阅读和维护。然而,在这个 的情况下,完整的课程足够小,以至于 的差别不是很大,当然,因为我们正在处理模板,所以在每个翻译单元中仍然必须包含实际定义 它使用它。
C++标准不存在“的”与问候类(或任何其他 )说。在模板实例化处,名称查找找到 DebugLog
,并发现它是一个类(因此是一个类型)。在那一点上, 它是一个不完整的类型,只有有限的东西,你可以做一个不完整的类型 。如果实例化的类模板 没有做任何需要完整类型的事情(并且Singleton
没有),那么没有问题。 (请注意,此时只有类 定义被实例化;类成员函数 在使用前不会被实例化。)
我可能会补充说,您发布的 代码中仍缺少一件重要的东西:声明 Singleton::instance
没有定义。您仍然需要添加:
template<typename T> T Singleton<T>::instance;
某处。
1)不,不管你如何构造你的代码。 Singleton
是不是一个类,顺便说一句:这是一个模板。由于无论如何,完整的模板定义必须在任何实例化站点都可访问,因此您可以定义所有内联。
2)class DebugLog : public Singleton<DebugLog>
很好。我们不是从一个不存在的阶级继承而来的;相反,我们从类Singleton<DebugLog>
继承。模板可以在不完整的类型上实例化。 (有几个规则,你可以做什么,不能做这样的类型参数。)
例如,template <typename T> class Foo { };
肯定可以在没有问题的任何类型上实例化。更有趣的是,template <typename T> struct PointerFactory { typedef T * type; };
可以在任何类型上实例化,完成与否。在目前情况下,CRTP中模板参数的目的仅仅是为了通知基类它的最终派生类型,所以这是完全正确的。
这是否意味着,当一个类继承模板类时,模板参数是什么并不重要,对吧? – Alcott
@Alcott:这与继承没有任何关系。唯一的问题是你是否可以实例化模板。 –
您必须在此情况下,使用指针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() {}
};
1 - 你不需要。 2 - [好奇地重复出现的模板模式](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)。 – birryree
@birryree,谢谢。 – Alcott