C++ 单例 vs 完全静态对象

2022-01-05 00:00:00 class static singleton c++

假设我们的项目中只需要某个类的一个实例.有几种方法可以做到这一点.

Let say we need to have just one instance of some class in our project. There are couple ways of doing it.

我想比较.请您检查一下我的理解.

I want to compare. Please can you review my understanding.

1) 经典的单例模式

2) 完全静态的类(所有方法和成员都是静态的).

2) Completely static class (all methods and members are static).


据我了解,差异如下:


As I understand the differences are following:

a) 未定义跨不同单元的静态成员的初始化顺序.因此,完全静态成员初始化不能使用来自其他模块的任何静态成员/函数.而单身人士则没有这个问题.

a) The order of initialization of static members across different units isn't defined. So, completely static members initialization can't use any static members/functions from other modules. And singleton doesn't have this problem.

b) 我们必须处理 Singleton 的 getInstance() 线程.但是,完全静态的类没有这个问题.

b) We have to deal with threading for getInstance() of Singleton. However, completely static class doesn't have this problem.

c) 对方法的访问看起来有点不同.Foo::bar();vs Foo::getInstance()->bar();一般单例可以返回NULL,说明对象构造有问题,静态类不能.

c) Access to methods looks a little bit different. Foo::bar(); vs Foo::getInstance()->bar(); Generally, singleton can return NULL to identify that there were some problems with construction of object and static class can't.

d) 类的定义看起来有点笨拙,静态类有一堆静态.

d) Definition of class looks a little bit clunky with bunch of statics for static class.

我错过了什么吗?

推荐答案

无论你称它为 Singleton 还是 Monostate 或任何花哨的名字......这个非常烦人的本质是你有一个对象的实例并且许多写入它:全局变量,无论其伪装如何,都是邪恶的.

Whether you call it Singleton or Monostate or any fancy name... the very annoying nature of this is that you have ONE instance of the object and many writes to it: global variables, whatever their guise, are evil.

您需要一个独特实例的想法通常很笨拙.大多数时候,您真正需要的是共享相同实例的通信部件.但是另一组零件可以完美地使用另一个实例而不会出现问题.

The idea that you need a unique instance is generally clunky. Most of the times what you really need is parts that communicate share the same instance. But another group of parts could perfectly use another instance without issue.

任何声称需要全局变量的代码都是高度可疑的.使用它可能看起来更简单,但让我们面对现实,您可以完美地将对象传递给每个函数,这会使它们的签名复杂化,但它仍然可以工作.

Any code that claim to need a global variable is highly suspicious. It may appear simpler to use one, but let's face it, you could perfectly pass the object to each and every function, it would complicate their signature but it would work nonetheless.

但是,我承认,使用全局变量似乎更简单……直到您注意到问题为止:

However, I admit, it appears simpler to use global variables... until you notice the issues:

  • 多线程受到威胁
  • 可测试性降低,因为一项测试可能会影响接下来的测试
  • 依赖性分析极其复杂:当您从子方法中提取全局时,很难知道您的方法依赖于什么状态...
  • multithreading is compromised
  • testability is reduced, since one test may affect the one following it
  • dependency analysis is extremely complicated: it's hard to know what state your method depend on when you pull in global from within submethods...

现在,就单例而言,在 C++0x 之前的 C++ 中无法使用多线程创建(当可以使用静态局部变量时),因此您只需要在一个线程中创建它并延迟访问之前:实例化主要是,这是你最好的选择.

Now, as far as singleton is concerned, multithreaded creation is not usable in C++ before C++0x (when it becomes possible using static locals), thus you need to create it in only one thread and delay access before: instantiate it in main, it's your best bet.

破坏可能会导致混乱,因为 Singleton/Static 的生命可能会在其他人完成之前结束,然后它是未定义的行为.这是典型的 Logger 单例.通常的策略是无耻地泄漏......

Destruction may cause mayhem since the life of the Singleton / Static may end before others are done with it, and then it's undefined behavior. This is typical of a Logger singleton. The usual strategy is to shamelessly leak...

在那之后,如果你还想要一个,祝你好运,这就是这个社区能为你做的一切.

After that, if you still want one, I wish you good luck, that's all this community can do for you.

相关文章