c++ singleton initialization order
I have
class Foo
class Bar
Now, I want
Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();
to both initialize before
int main()
is called.
Furthermore, I want
Foo::singleton
to initialize开发者_运维技巧 before
Bar::singleton
Is there anyway I can ensure that?
Thanks!
Global variables (like the singletons) that are defined in the same translation unit are initialized in the order in which they are defined. So put the definition of both singletons in the same source file, in the correct order.
If they would be defined in different source files the order in which they are initialized would be unspecified (the "static initialization order fiasco").
See also Static variables initialisation order
For gcc use init_priority:
http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
Works across different translation units. So your code would read:
Foo* Foo::singleton __attribute__ ((init_priority (2000))) = new Foo();
Bar* Bar::singleton __attribute__ ((init_priority (3000))) = new Bar();
I don't have gcc handy right now so I can't verify this, but I have used it before. The other simpler and more portable solution is to avoid static initialization, and explicitly create the singletons in order at some well defined place within 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
...
}
Remember, things will get just as gnarly with singletons on the way out of the program as well, so its often better to make it explicit.
#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;
}
Output:
Foo()
main()
In a nutshell:
// smooth.cpp
#include "foo.h"
#include "bar.h"
Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();
A nice syntax, to avoid worrying about that:
Foo& Foo::singleton()
{
static Foo Singleton;
return Singleton;
}
The good thing about this syntax, is that the singleton is initialized at the first call of the method, thus you don't have to worry (usually) when it happens, since when calling the method to access it you get it anyway :)
精彩评论