我在这里做了一些关于这个主题的关于stackoverflow的研究,但是我没有从我可以学习的地方找到一个单独的答案,singleton类是如何工作的。我已经知道一个单例类只能有一个实例。有人可以解释我- 或者链接我一个教程 -如何创建最基本的单例类,并逐行告诉我为什么/它是如何工作的? 我有麻烦的是,我抬头的答案和一些教程并没有真正解释为什么我应该声明某个变量或函数为静态,指针等如何在C++中创建一个简单的单例类?
回答
Discalimer
一般一个应尽量避免使用单身和/或全局对象。应该明确传递函数所需的对象。这使得在并行代码时通过传递模拟对象,调试和减少争用来轻松测试函数。例如,我的应用程序中唯一的全局对象是记录器(类似于标准I/O流)和线程特定的事件循环引擎。
使用单例或全局对象的唯一原因是为了避免在所有函数调用中传递它的麻烦。例如。您不希望通过每次调用传递一个记录器对象,但不需要创建许多本地或成员记录器对象以节省空间和时间。
方法1
最基本的单是在运行过程中,在动态初始化阶段初始化的全局对象,如:
// singleton.h
class Singleton { /*...*/ };
extern Singleton singleton;
// singleton.cc
#include "singleton.h"
extern Singleton singleton(/*...*/);
好处:
- 在输入
main
之前初始化。 - 线程安全初始化。
- 非侵入性,不要求该类是“单身人士”。它是对象
singleton
什么是单身人士,而不是班级本身。
缺点:
- 一些构造函数的参数
main
之前可能无法使用。
这样的对象也可以main
之前使用的通过确保它被使用Schwarz Counter第一访问之前初始化(同样的方法std::cout
和朋友得到初始化)进入。
方法2
另一种选择是有一个全球性的指针的对象。该指针在main
的早期初始化,并在main
堆栈上创建一个对象。
E.g.:
// singleton.h
class Singleton { /*...*/ };
extern Singleton* singleton;
// main.cc
int main() {
Singleton the_singleton(/*...*/);
singleton = &the_singleton;
// at main end
singleton = nullptr;
}
益处的那些方法的1
方法3
函数作用域静态在C++ 11(GCC这样做之前C++ 11) object:
// singleton.h
class Singleton { /*...*/ };
Singleton& get_singleton();
// singleton.cc
Singleton& get_singleton() {
static Singleton singleton;
return singleton;
}
Benefit其和缺点的那些方法1.
方法4
双检锁定单的。 Not necessary in C++11,作为功能范围静态为您执行线程安全初始化。
我的理解是应该只有一个实例。你的答案如何证明这个概念? – 2014-11-20 20:49:24
@ThomasMatthews从流程的角度来看,单一类的对象可以有多个实例。如果组件需要访问同一个对象,他们通过相同的名称访问它,例如:'singleton.foo()','singleton-> foo()','get_singleton()。foo()'。你可以强制规定这个类只有一个对象,但根据我的经验,这很少是必需的。 – 2014-11-20 21:04:01
谢谢你的一切!我正在尝试创建一个游戏,并且我想创建一个加载并绘制所有动画精灵(图像)的类。现在,如果我创建了一个简单的类,没有任何东西阻止我(或任何人)创建该类的多个实例,但我只需要一个对象来处理所有的绘图和加载。我从书中得到了它的代码,但我不明白它是如何工作的。 – 2014-11-20 21:06:20
勺子男孩:不要尝试和单独的班级。这是
不可能的。不好的做法。相反......只是尝试意识到事实。Neo:什么道理?
勺子男孩:没有单身。
Neo:没有单身?
勺子男孩:然后你会看到,它不是只限于一个实例的类,它只是你需要一个实例。
我想说的是:作为一个类的作者,永远不要强迫这个类是一个单身人士。仅仅因为您认为系统今天只需要一个Logger
对象,并不意味着明天您可能不需要两个(例如一个用于Windows应用程序事件日志,一个用于系统事件日志)。
认为你的thread_pool
类应该是单身?那么,我需要一个公平的线程池和一个我的应用程序中的LIFO线程池。
如果您创建N个Agent
对象,他们都需要共享一个Logger
对象,不写Logger
为单 - 而使用这样的:
// agent.h
class Agent {
...
private:
Logger& GetLogger();
}
// agent.cpp
Logger& Agent::GetLogger() {
static Logger TheOne;
return The One;
}
毕竟,这是Agent
需要Logger
是单身人士 - 而不是Logger
本身!
- 1. 在Objective C中创建单例类的另一个实例
- 2. 如何在Objective-C中创建一个简单的整数?
- 3. 如何在scala/lift中创建一个简单的web表单
- 4. 如何在Unity中创建一个通用的单例类?
- 5. 创建一个简单的2D AI C++
- 6. 如何创建一个简单的VPS
- 7. 如何在C中创建一个单例?
- 8. 如何在Angular SPA中创建一个简单的“构建”
- 9. 创建一个简单的Python菜单
- 10. 创建一个简单的IVR菜单
- 11. 创建一个单例类访问ServiceSecurityContext.Current.WindowsIdentity
- 12. 在C#中创建简单的Xml
- 13. 如何在C++中创建一个类的多个实例
- 14. 如何创建一个简单的C#http monitor/blocker?
- 15. 如何创建一个简单的段落类
- 16. 在Visual C++中创建一个简单的PHP解释器
- 17. 在C#中创建一个简单的脚本语言
- 18. 如何创建派生类的单例?
- 19. 如何在android中创建一个简单的文本动画?
- 20. 如何在java中创建一个简单的状态机
- 21. 如何在java中创建一个简单的加密算法?
- 22. 我将如何在Python中创建一个简单的URL extracter?
- 23. 如何在任务栏中创建一个简单的动画?
- 24. 如何在Android NDK中创建一个简单的NDK程序
- 25. 你如何在球拍中创建一个简单的变量?
- 26. 创建一个非常简单的单循环列表C#
- 27. 如何在C++中只创建一个实例的类
- 28. 如何在另一个类中创建一个类的实例
- 29. 在Rails中创建一个简单的下拉菜单
- 30. 如何在Java中创建一个不可变的单例?
请参阅http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 – statueuphemism 2014-11-20 20:40:07
然后,您应该首先了解静态指针和指针! – Venkatesh 2014-11-20 20:40:11
在Singletons上找不到任何有用的东西?这很难相信... – Borgleader 2014-11-20 20:42:16