单例模式 - 受保护的构造函数 vs 私有构造函数

13

在设计单例模式时,为什么构造方法被设为protected而不是private?这是我在网上看到的。

我们想要控制该类所创建的实例数量,这很合理,但为什么要使用protectedprivate不也可以吗?


9
如果有人决定单例模式是一个好主意,那么你应该预期他们的代码会有其他荒谬的设计决策,并且不应该试图从中学到任何东西。 - Mike Seymour
3个回答

9
首先,在绝大多数情况下,单例模式都是一个不好的主意(为什么?)。使用它们的频率比全局变量还要低。
这样子类就可以实例化单例基类,并在自己的GetInstance()类型函数中将其作为自己的一部分返回。这就是在设计模式中这样做的原因。因此,只有在计划从Singleton继承时,它才真正相关。
GoF说(第130页,子类化Singleton类);

更灵活的方法使用一个Singleton注册表。单例类可以通过名称在众所周知的注册表中注册其单例实例,而不是让Instance定义可能的单例类集。

在使用单例注册表时,仍然需要在基本Singleton中使用protected构造函数(根据给定的实现)。
简而言之,如果您计划从Singleton继承,则将其设置为protected。否则,选择private

@dj aqeel:“全局变量和单例已经被公认为是设计反模式”http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html - Eddy Pronk
1
@dj: (a) 全局可访问的对象会使设计缺乏结构,因此很难跟踪对象间的依赖关系。这会使大型项目更难维护。(b) 实施特定生命周期管理的对象会使测试变得更加困难,因为它们不能在测试期间创建和销毁。也许这道问题中的“受保护”构造函数是为了减少这种影响;使用“公共”构造函数会更好。(c) “静态初始化混乱”和线程安全问题使它们难以在C++03中正确实现(尽管C++0x将修复这个问题)。 - Mike Seymour

4

使用单例模式是不好的。没什么好说的。

话虽如此,构造函数可以是私有的,没有问题。但是如果您想从单例派生另一个单例(好像拥有一个单例还不够糟糕一样)?在这种情况下,派生类需要访问基础单例的构造函数。


7
我非常想点赞这个观点,但是单例并不是在所有情况下都是不好的。它们经常被误用,但不要因此反对这种设计模式! - Yuck
假设你真的需要一个单例(我不在乎这是否“不可能”,让我来阐述我的观点)。如果它让你绕过“只有一个类限制”,那么放弃它并使用全局变量不是更好吗? - R. Martinho Fernandes
1
@Ron_s:没错。但我不明白你为什么在例子中包含了<iostream> :)))) - Armen Tsirunyan
我有一个准备好的 .cpp 文件用于修改和程序测试,有时候我使用cout及其相关函数,所以我只是复制粘贴了它们(抱歉) :) - Ron_s
2
@Ron_s:cout 明显是女性,我反对你的男性主导假设。 - Kerrek SB
显示剩余7条评论

0

这一切都与继承有关。 class lazy_singleton: public singleton {}; 将是具有singleton构造函数的相同singleton


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接