我遇到了这个页面,它对单身人士有一个非常好的、全面的概述。
代替常见的“单例是一个具有私有构造函数且只有一个全局实例的类”,它描述了单例如下:
准确定义我们所说的“单例”是很重要的。
就本论点而言,单例是任何可变状态,无需从堆栈开始即可到达(即从静态或全局变量可到达)。
通常,单例是作者期望只有一个实例的类。但是,就我们的目的而言,任何可全局访问的对象都很重要。
例子:
- 一组操纵某些共享可变状态的函数(或静态方法)构成一个单例。
- 如果单例 A 提供对可变对象 B 的引用,则 B 也是单例。
- 这意味着单例集合的每个可变成员本身就是一个单例。
- 即使全局可访问,传递不可变对象也不是单例。它是一个常数。
- 假设代码是不可变的,不访问任何单例的独立函数本身不是单例。
...
那么 open() 或标准输出呢?
这些是单身人士的一些最糟糕的例子!
...
从本质上讲,这意味着 , malloc
,new
或shared_ptr
任何你的语言用来访问堆内存的东西——所有这些都使用单例!
然而,没有人说我们需要因此避免堆分配。内存分配似乎到处都被忽视了!即使在我引用的页面上,他们也提到了open()
和stdout
日志记录,但他们从未提到堆内存分配——这显然比记录器更“危险”,因为它不是单向街道。
所以我的问题是,内存分配是规则的一个例外(为什么?),还是单例的一个坏例子?
我如何确定单身人士的新用途是否属于同一“例外”类别?
(出于显而易见的原因,标记为与语言无关,但也标记为 C++,因为我认为它与 C++ 特别相关,因为它允许用户修改行为new
并引入更多全局状态。)