单例初始化

Jir*_*Jir 1 c++ singleton private-members

我在代码中实现了Singleton设计模式.

假设它是:

class Singleton
{
  Singleton () {}
  static Singleton* s;
public:
  static Singleton* Get () {
    if (!s)
      s = new Singleton ();
    return s;
  }
};
Run Code Online (Sandbox Code Playgroud)

令我困惑的是这种模式的"初始化".在.cpp我把:

SingletonPointer* SingletonClass::s (0);
Run Code Online (Sandbox Code Playgroud)

但我不明白如何才能访问 define s,因为它是如此private.怎么可能?

TIA,吉尔

Joh*_*ing 9

使用Singleton模式的最佳方法是根本不使用它.

单身人士为何不好的简要总结:

  1. 它们是具有特殊限制的全局变量.由于他们自己的原因,全球足够糟糕; 让他们成为单身只是放大了坏处.
  2. 如果你真的只需要一个对象的一个​​实例,那就做一个.如果您需要一个特殊的设备来确保您不会生成多个设备,那么代码的语义就会出现问题.使它成为一个单身并不能解决这个问题,它只是用新的问题来论证它.
  3. 单身人士对线程并不好看.线程很难.不要让他们更难.

使用Singleton 不能解决任何问题.它只是将错误的语义应用于现有代码,使得该代码的未来扩展变得困难或不可能(如果明天你需要两个?),并添加新的问题.长话短说,就是不要使用它们.

  • @James:然后不要创建第二个. (3认同)
  • @RedX:我对这篇文章感兴趣,我知道很多缺点但是将它们稍微正式化以备将来参考会很好:) (2认同)
  • @Matthieu:的确,我在反对Singleton"模式",而不是使用全局变量(我认为偶尔是一个很好的解决方案).我从来没有听说过防止类的多个实例的有效案例,也没有看到Singletons伪装成全局变量以外的任何东西; 如果有人有一个例子,我会感兴趣. (2认同)
  • @James:我不同意.在这个例子中,我的断言"如果你只需要一个,那么只需创建一个"适用.logger对象通常由某个Application类型对象拥有,您只创建其中一个.你不需要去寻找它.只需执行`my_app-> GetLogger() - > DoTheThing();` (2认同)
  • @James Kanze:您可以通过全局函数访问它来解决初始化顺序问题,其中它是一个静态变量(有一些关于线程安全的警告[将在C++ 0x中修复,并且已经在大多数编译器]和销毁订单),或者在问题中创建(必要时解决线程安全问题).这是一个完全独立的问题,以防止多个实例,你仍然没有提供一个为什么你想要除了"因为一些疯子把它放在规范中"的例子. (2认同)

Boa*_*niv 5

除了声明之外,静态字段必须具有定义.声明通常在.h文件中的类声明中,而定义几乎总是在.cpp文件中.静态变量的定义是必须的,因为它们必须初始化为某些东西.

但即使定义在类体之外,甚至在完全不同的文件中,也并不意味着它不是类的一部分.它SingletonClass::使它成为类定义的一部分(而不是类声明),因此它可以"访问"私有字段.

对于在类体外部定义的方法也是如此,例如:

// A.h
class A
{
private:
    int b;
public:
    A(int x) : b(x)
    {}

    Do();
}

// A.cpp
A::Do()
{
    return b;
}
Run Code Online (Sandbox Code Playgroud)