Sign in to follow this  

Singleton Quest?

This topic is 4694 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, I have some question about using Signleton class would like to discuss with you guys. When we decide a singleton, sometimes we do this, Example 1:
class A 
{
 private :
   A();
 public :
   static A* GetInstance() 
   {
    static A a; 
    return &a;
   }
}; 
This is absolutly good, but when compile in release mode, the compiler will sometimes make the GetInstance() inline, and it may causes the problem. So, another way to write a singleton class is, Example 2:
class A
{
 private :
   static A a;
   A();
 public:
   static A* GetInstance()
   {return &a};
};
It work fines even when the compiler change the GetInstance() to inline. But by doing that, we cannot control the order of when the singleton will be created, which is one of the main properties of a singelton class. Well, some of the solution I know for Exampl 1 is that we enforce the compiler not to change the GetInstance() to be inlined. Which I am not sure how can I do it in Visual .Net. Also, I don't know whether the command to do this is complier dependent. However, personally, I don't think it is a good solution since the function GetInstance() is so simple, and it should be inlined. By enforce the compiler to make it not inline may not be a very good approach. Another problem of using Singleton is that if the class require some parameters to pass into the constructor, what is the best solution for that? Also, if I want to do a subclass from a Singleton, what is the best way to do that too? Thanks! Edit: added [ code ] tags. [Edited by - hplus0603 on February 10, 2005 2:04:23 PM]

Share this post


Link to post
Share on other sites
How about:


class A
{
static A *singleton;
void createSingleton()
{
singleton = new A();
}
void getSingleton()
{
return singleton;
}
};


This way you can control the order in which it's created, by calling createSingleton().

Cheers!

[edit] Or better yet, put the code in createSingleton() into the constructor, and you can then merely do:

new A();

To setup the singleton.

Share this post


Link to post
Share on other sites
Quote:


static A* GetInstance()
{
if ( !a )
{
a = new A;
}
return a;
}



That's pretty much what the compiler generates for the function static instance code, too; you just made it explicit. The problem with all of those approaches is that it's not thread-safe, so if two threads try to initialize the variable at the same time, you're screwed.

Usually, you don't create threads in your static constructors, though, so you can get around this by using the function-static instance, but then ALSO creating a static object whose only job it is to call the GetInstance() function to make sure the singleton is created when you hit main().

Note: the semantics of the function-level static are very clear in the standard. If writing the original code "causes problems" with inlining, then the compiler is broken, and you should upgrade. Neither latest GCC nor latest MSVC have a problem with that code, AFAICT.

Something like this should be sufficient for all uses:


template< class T > class Singleton {
public:
Singleton() { (*this)(); }
T * operator()() {
static T t;
return &t;
}
static Singleton it;
};

Singleton< MyClass > gMyClassInstance;

// Two alternative uses, either is fine:
MyClass * single = gMyClassInstance();
MyClass * single = Singleton< MyClass >::it();

Share this post


Link to post
Share on other sites
Hello,

Thanks for replay! However, the method that make a function called CreateSinglton() doesn't work since it requires the user to explicitly
create the singleton first, which may not always be possible, like, if
we have a static class that referencing the singleton class
in it constructor, then the progam will get a NULL pointer from GetInstance()eg,

class A
{
static A *singleton;
void createSingleton()
{
singleton = new A();
}
void getSingleton()
{
return singleton;
}

void f();
};

class B
{
static B b;

public :
B()
{a->getSingleton()->f();};
}


Thanks!





Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603

Note: the semantics of the function-level static are very clear in the standard. If writing the original code "causes problems" with inlining, then the compiler is broken, and you should upgrade. Neither latest GCC nor latest MSVC have a problem with that code, AFAICT.



Well, I am not sure about this, cause I get the problem on the lastest XBox compiler. I am not 100% sure whether the compiler in Visual Studio is the same one on XBox. I only know that they somehow related. Ha!

Thanks

Share this post


Link to post
Share on other sites
Well, in my engine I create all singletons at engine startup (because, being singletons, they are probably large, hulking classes that only need be initialized once and deinitialized once). If you can't do that:


class A
{
static A *singleton;
A()
{
assert( !singleton );
singleton = this;
}
static get()
{
if ( !singleton )
{
new A();
}
return singleton;
}
};


This shouldn't have much of a performance impact (as compared to your first one) and should allow you control over when the singleton is made plus shouldn't be a problem for inlining. At least I think.

Hope it helps!

[edit] Ah, didn't see previous post. Sorry :).

Share this post


Link to post
Share on other sites

This topic is 4694 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this