使用Singleton初始化程序

时间:2009-05-24 12:29:16

标签: c++ design-patterns singleton

我读了很多关于为什么单身人士不好的文章 我知道它很少用于记录,但是有关初始化和去初始化的内容 这样做有什么问题吗? 我有一个脚本引擎,我需要在启动时绑定到库 图书馆没有main()所以我应该使用什么?
常规功能或单身人士 可以以某种方式复制此对象:

class
{
public:
   static void initialize();
   static void deinitialize();

}  bootstrap;

如果不是,为什么人们会隐藏副本ctor,赋值运算符和ctor?

4 个答案:

答案 0 :(得分:4)

C ++中的库有一种更简单的方法来执行初始化和清理。它与其他任何东西完全相同。 RAII。

包装需要在类中初始化的所有内容,并在构造函数中执行其初始化。瞧,问题解决了。

单身人士的所有常见问题仍然适用:

  • 将需要多个实例,即使你没有计划它。如果没有别的,你会在单元测试时想要它。每个测试都应该从头开始初始化库,以便它在干净的环境中运行。单身方法很难做到这一点。
  • 一旦这些单身人士开始引用彼此,你就会被搞砸。因为实际的初始化顺序是不可见的,所以你很快会得到一堆循环引用,导致访问未初始化的单例或堆栈溢出或死锁或其他有趣的错误如果你没有那么可能在编译时被捕获痴迷于使一切变得全球化
  • 多线程。强制所有线程共享同一个类实例通常是一个坏主意,因为它迫使该类锁定并同步所有,这会导致很多性能,并可能导致死锁。 / LI>
  • 意大利面条代码。每次使用单例或全局时,您都隐藏了代码的依赖关系。不再清楚函数所依赖的对象,因为并非所有对象都作为参数可见。而且因为您不需要将它们作为参数添加,所以最终会添加远远超过必要的依赖项。这就是为什么一旦你拥有单身几乎不可能被移除的原因。

答案 1 :(得分:1)

单身人士的目的是在你的系统中只有一个特定类的一个实例。 C'tor,D'tor和CC'tor是隐藏的,以便有一个接入点来接收唯一的现有实例。

通常实例是静态的(也可以在堆上分配)和私有,并且有一个静态方法(通常称为GetInstance),它返回对此实例的引用。

在决定是否拥有单身时,你应该问自己的问题是:我真的需要强制执行这个类的一个对象吗?

还存在继承问题 - 如果您计划从单例继承,它可能会使事情变得复杂。

另一个问题是How to kill a singleton(网页上有关于此问题的文章)

在某些情况下,最好是静态保存私人数据,而不是拥有单身,这一切都取决于域名。

但请注意,如果你是多线程的,那么静态变量会给你带来痛苦......

因此,在决定您将要使用的设计模式之前,您应该仔细分析您的问题......

在您的情况下,我认为您不需要单例,因为您希望在开始时初始化库,但它与强制只有一个类的实例无关。你只需要保持一个静态标志(静态bool已初始化)即可确保只初始化一次。

调用一次方法不足以构成一个单例。

答案 2 :(得分:0)

为库提供接口是一个很好的做法,这样多个模块(或线程)就可以同时使用它们。如果你真的需要在加载模块时运行一些代码,那么使用单例来初始化部件 必须初始化一次。

答案 3 :(得分:0)

计算您设计中的单身人数,并将此号码称为'

计算设计中的线程数,并将此数字称为“t”

现在,提高到第s次幂;这大致是调试结果代码时可能丢失的头发数量。

(我个人已经碰到了代码,这些代码有超过50个单身,有10个不同的线程,所有人都争先恐后地去.getInstance())