c ++单例初始化顺序

时间:2010-02-17 04:43:59

标签: c++ singleton initialization

我有

class Foo
class Bar

现在,我想要

Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();

之前初始化
int main()

被召唤。

此外,我想要

Foo::singleton

之前初始化
Bar::singleton

无论如何我能确保吗?

谢谢!

4 个答案:

答案 0 :(得分:3)

在同一翻译单元中定义的全局变量(如单例)按照定义它们的顺序进行初始化。因此,将两个单例的定义放在同一个源文件中,顺序正确。

如果它们将在不同的源文件中定义,那么它们的初始化顺序将是未指定的(“static initialization order fiasco”)。

答案 1 :(得分:2)

另见Static variables initialisation order

对于gcc,请使用init_priority:

http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

适用于不同的翻译单位。所以你的代码会读到:

Foo* Foo::singleton __attribute__ ((init_priority (2000))) = new Foo();
Bar* Bar::singleton __attribute__ ((init_priority (3000))) = new Bar();

我现在没有gcc方便,所以我无法验证这一点,但我之前使用过它。 另一个更简单,更便携的解决方案是避免静态初始化,并在main中的某个明确定义的位置显式创建单例。

// Nothing in static area

void main(void)
{
  // Init singletons in explicit order
  {
    Foo* Foo::singleton = new Foo();
    Bar* Bar::singleton = new Bar();
  }

  // Start program execution
  ...
}

请记住,在离开程序的过程中,单身人士的事情也会变得非常粗糙,因此通常最好将其明确化。

答案 2 :(得分:0)

#include <iostream>

class Foo {
public:
  static Foo *singleton ()
  {
    if (foo == NULL)
      foo = new Foo;
    return foo;
  }
private:
  Foo ()
  {
    std::cout << "Foo()\n";
  }
  static Foo *foo;
};

Foo *Foo::foo = NULL;

Foo *singleton = Foo::singleton ();

int
main ()
{
  std::cout << "main()\n";
  return 0;
}

输出:

Foo()
main()

答案 3 :(得分:0)

简而言之:

// smooth.cpp
#include "foo.h"
#include "bar.h"

Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();

一个很好的语法,以避免担心:

Foo& Foo::singleton()
{
  static Foo Singleton;
  return Singleton;
}

关于这种语法的好处是,单例在第一次调用方法时被初始化,因此你不必担心(通常)它何时发生,因为当调用方法访问它时你会得到它无论如何:)