tags:

views:

1669

answers:

9
+5  A: 

You can avoid needing to delete it by using a static object like this:

if(m_pA == 0) {
    static A static_instance;
    m_pA = &static_instance;
}
Evan Teran
Big note: if you are using multithreading, you should be incredibly careful about doing this. See http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function for why it is a very very bad idea in general.
hazzen
very good point, which is why when using multiple threads there should be mutexes or some other synchronization primitives involved.
Evan Teran
Just don't even try and implement it using double locking, because that can NOT be made to work correctly in C++ (see google for details).
Martin York
Add gcc has an explicit patch to (read non-standard) to cope with this.
Martin York
The best way is to decouple referencing and creation and have the main thread create all singletons before starting any threads that may reference a singleton. Btw returning a reference is in most cases superior to returning a pointer...
Andreas Magnusson
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf is a good reference on the double checked locking issues in C++.
xtofl
Gotta love the random downvote 2 years after the fact with no explanation :-P
Evan Teran
+1  A: 

I do not think there is any reason to write that line no. Your destructor method is not static and your singleton instance will not be destructed in that fashion. I do not think the destructor is necessary, if you need to cleanup the object use the static method you've alread created, FreeInstance().

Other than that, you create your singletons in roughly the same way that I create mine.

Odd
+2  A: 

A singleton in C++ can be written in this way:

static A* A::GetInstance() {
    static A sin;
    return &sin;
}
sep
+1  A: 

Just don't forget to make the copy constructor and assignment operators private.

Jasper Bekkers
+12  A: 

Why does everybody want to return a singelton as a pointer?
Return it as a reference seems much more logical!

You should never be able to free a singelton manually. How do you know who is keeping a reference to the singelton? If you don't know (or can't guarantee) nobody has a reference (in your case via a pointer) then you have no business freeing the object.

Ue the static in a function method.
This guarantees that it is created and destroyed only once. It also gives you lazy initialization for free.

class S
{
    public:
        static S& getInstance()
        {
            static S    instance;
            return instance;
        }
    private:
        S() {}
        S(S const&);              // Don't Implement.
        void operator=(S const&); // Don't implement
 };

Note you also need to make the constructor private. Also make sure that you override the default copy constructor and assignment operator so that you can not make a copy of the singelton (otherwise it would not be a singelton).

Also read:
http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used

To make sure you are using a singelton for the correct reasons.

Though technically not thread safe in the general case see:
http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function

GCC has an explicit patch to compensate for this:
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg00265.html

Martin York
Another benefit of references is that it is not possible to do this: 'delete A::getInstance()', which is possible with pointers.;
yoav.aviram
I guess everybody wants to optimize prematurely, and they feel like in control when they do the pointer thing.However, even the 'static S instance' clause is to be compiled to a thread-safe construct! Is it?
xtofl
A: 

There is greate C++ library ACE which bas on pattenrns The wrote a lot of doc's about different kind of patterns so look at theyre work. http://www.cs.wustl.edu/~schmidt/ACE.html

A: 

After a period of wild enthusiasm for Meyers-style singletons (using local static objects as in some of the previous answers), I got completely sick of the lifetime management problems in complicated apps.

I tend to find that you end up referencing the 'Instance' method deliberately early in the app's initialisation, to make sure they're created when you want, and then playing all kinds of games with the tear-down because of the unpredictable (or at least very complicated and somewhat hidden) order in which things get destroyed.

YMMV of course, and it depends a bit on the nature of the singleton itself, but a lot of the waffle about clever singletons (and the threading/locking issues which surround the cleverness) is overrated IMO.

Will Dean
+1  A: 

if you read "Modern C++ Design" you'll realize that a singleton design could be much complex than return a static variable.

jab
A: 

This implementation is fine as long as you can answer these questions:

  1. do you know when the object will be created (if you use a static object instead of new? Do you have a main()?)

  2. does you singleton have any dependencies that may not be ready by the time it is created? If you use a static object instead of new, what libraries have been initialized by this time? What your object does in constructor that might require them?

  3. when will it be deleted?

Using new() is safer because you control where and when the object will be created and deleted. But then you need to delete it explicitly and probably nobody in the system knows when to do so. You may use atexit() for that, if it makes sense.

Using a static object in method means that do do not really know when it will be created or deleted. You could as well use a global static object in a namespace and avoid getInstance() at all - it doesn't add much.

If you do use threads, then you're in big trouble. It is virtually impossible to create usable thread safe singleton in C++ due to:

  1. permanent lock in getInstance is very heavy - a full context switch at every getInstance()
  2. double checked lock fails due to compiler optimizations and cache/weak memory model, is very tricky to implement, and impossible to test. I wouldn't attempt to do it in a real system, unless you intimately know your architecture and want it to be not portable

These can be Googled easily, but here's a good link on weak memory model: http://ridiculousfish.com/blog/archives/2007/02/17/barrier.

One solution would be to use locking but require that users cache the pointer they get from getInctance() and be prepared for getInstance() to be heavy.

Another solution would be to let users handle thread safety themselves.

Yet another solution would be to use a function with simple locking and substitute it with another function without locking and checking once the new() has been called. This works, but full implementation is complicated.

n-alexander