【发布时间】:2013-03-28 18:33:40
【问题描述】:
我遇到了this page,它对单身人士有一个非常好的、全面的概述。
与常见的“Singleton 是一个具有私有构造函数且只有一个全局实例的类”不同,它对 Singleton 的描述如下:
准确定义“单例”的含义很重要。
就本论点而言,单例是任何不从堆栈开始即可到达的可变状态(即从静态或全局变量可到达)。
通常,单例是作者希望只有一个实例的类。但是,就我们的目的而言,任何可全局访问的对象都很重要。
示例:
- 一组操作某些共享可变状态的函数(或静态方法)构成一个单例。
- 如果单例 A 提供对可变对象 B 的引用,则 B 也是单例。
- 这意味着单例集合的每个可变成员本身就是一个单例。
- 即使可全局访问,传递不可变对象也不是单例。这是一个常数。
- 不访问任何单例的独立函数本身不是单例,假设代码是不可变的。
...
open() 或 stdout 呢?
这些是单例最糟糕的例子!
...
这意味着,基本上,malloc、new、shared_ptr,或者任何你的语言用来访问堆内存的东西——所有这些都使用单例!
然而,没有人说我们需要因此避免堆分配。 内存分配似乎到处都被忽视了!即使在我引用的页面上,他们也提到了open() 和stdout 以及日志记录,但他们从未提及堆内存分配——这显然比记录器更“危险”,因为它不是单向街道.
所以我的问题是,内存分配是规则的一个例外(为什么?),还是也是单例的一个坏例子?
我如何确定单身人士的新用途是否属于同一“例外”类别?
(出于显而易见的原因,标记为与语言无关,但也标记为 C++,因为我认为它与 C++ 特别相关,因为它允许用户修改 new 的行为并引入更多全局状态。)子>
【问题讨论】:
-
单身人士的定义很奇怪。它似乎根本不包括它的“单一”部分。编辑:它几乎不符合单例的实际定义。 =/
-
@sftrabbit:它似乎关注与您在其他定义(“全局状态”)中看到的单例相同的问题,并且内存管理当然涉及 single(默认) 具有全局状态的内存管理器,对吧?
-
是的,他们定义的只是全局状态。
-
好吧,
malloc(等)没有可观察到的副作用(除了二进制“它是否可以分配内存”)。因此,尚不清楚假设的非单例malloc会带来什么优势。但最终,只有一个地址空间(在标准操作系统中)!这个事实需要以某种方式表达...... -
@sftrabbit:呃,我的意思是,每种语言的运行时内存管理器都是单例的例子吗?根据上面的定义,但如果你不这么认为,那么我很想知道为什么! (或许可以回答?)
标签: c++ oop language-agnostic singleton