4

In C++, can all the members in a singleton be static, or as much as possible? My thought is, there is only one instance globally anyway.

While searching I did find a lot of discussions on static class in C#, but not familiar about that. Would like to learn about it too.

Whatever thought you have, please comment.

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
Derek
  • 1,085
  • 2
  • 20
  • 36

5 Answers5

7

With a static singleton you can't control when the single will be allocated and constructed. This puts you at the mercy of the c++ order of construction rules for static variables, so if you happen to call this single during the construction of another static variable, the single may not exist yet.

If you have no intentions of ever calling the singleton from the constructor of another static variable, and do not wish to delay construction for any reason, using a static variable for singleton is fine.

See Static variables initialisation order for more info.

Community
  • 1
  • 1
goji
  • 6,911
  • 3
  • 42
  • 59
  • That is not true. It depends on how you construct the singleton. A singleton created by `new` has a definite starting point. Examples of this can be seen in Ogre3D SDK. – Vite Falcon Dec 11 '12 at 02:13
  • I've never seen a C++ singleton that was *not* a static variable. Either a `T*`, or a local static `T` (a Meyers' singleton). The question instead concerns whether the singleton's *data members* can reasonably be static, and for those members (but not the singleton itself) the above description holds. – Cheers and hth. - Alf Dec 12 '12 at 22:06
1

The singleton pattern, as you probably know, contains a static method Instance which will create the instance if and only if it exists and return that instance. There is no reason that other or all methods of the singleton could not be static. However, given that there is ever only one instance of the class i'm not sure it makes sense to make everything else static. Does that make sense?

Bejmax
  • 945
  • 7
  • 16
  • Not always the case. Read my comment for @Troy's answer. – Vite Falcon Dec 11 '12 at 02:14
  • im not sure what you mean. the singleton pattern i'm speaking of is created by new, in a static method. – Bejmax Dec 11 '12 at 03:47
  • That's bad by design. Who deletes the pointer then? Either way, I was commenting on your statement of 'as you probably know, contains a static method instance which will create the instance if an only if it exists...'. I was pointing out that's not the only way. You can create the singleton *outside* of the static method. – Vite Falcon Dec 11 '12 at 07:26
  • i understand, thanks. The singletons i've seen (and i avoid them at all costs) are created once and never deleted for the life of the program. Singleton should be a last resort in any case. – Bejmax Dec 11 '12 at 13:28
1

Much of the point of a singleton is to have some control over when it's created.

With static data members you forfeit that control, for those members.

So it's less than smart doing that.

That said, singletons are generally Evil™ with many of the same problems as pure global variables, including the tendency to serve as an uncontrollable communications hub that propagates various unpredictable effects rather willy-nilly from unpredictable places to other unpredictable and largely unknown places, at unpredictable times.

So it's a good idea to think hard about it: is a singleton really the answer, or could it, in the case at hand, be just a way to compound the problem it was meant to solve?

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

To answer your question: The case you're suggesting is more like a 'static class' in C# and C++ doesn't have a concept of 'static class'.

Usually in a C++ singleton class, the only static data member is the singleton instance itself. This can either be a pointer to the singleton class or a simply an instance.

There are two ways to create a singleton class without the singleton instance being a pointer.

1)

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        static MySingletonClass instance;
        return instance;
    }

    // non-static functions

private:
    // non-static data-members
};

2)

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        return sInstance;
    }

    // non-static functions

private:
    static MySingletonClass sInstance;
    // non-static data-members
};
// In CPP file
MySingletonClass MySingletonClass::sInstance;

This implementation is not thread-safe, not predictable in terms of when it gets constructed or when it gets destroyed. If this instances depends on another singleton to destroy itself, it can cause unidentifiable errors when exiting your application.

The one with the pointer looks something like this:

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        return *sInstance;
    }
    static MySingletonClass* getInstancePointer()
    {
        return sInstance;
    }

    MySingletonClass()
    {
        if (sInstance) {
            throw std::runtime_error("An instance of this class already exists");
        }
        sInstance = this;
    }

    // non-static functions

private:
    static MySingletonClass* sInstance;
    // non-static data-members
};

Inialization of such a singleton class would usually happen during application initialization:

void MyApp::init()
{
    // Some stuff to be initalized before MySingletonClass gets initialized.
    MySingletonClass* mySingleton = new MySingletonClass(); // Initalization is determined.
    // Rest of initialization
}

void MyApp::update()
{
    // Stuff to update before MySingletonClass
    MySingletonClass::getInstance().update(); // <-- that's how you access non-static functions.
    // Stuff to update after MySingletonClass has been updated.
}

void MyApp::destroy()
{
    // Destroy stuff created after singleton creation
    delete MySingletonClass::getInstancePointer();
    // Destroy stuff created before singleton creation
}

Although the initalization and destruction of singleton is controlled in this scenario, singletons don't play well in a multi-threaded application. I hope this clears your doubts.

Vite Falcon
  • 6,575
  • 3
  • 30
  • 48
0

the short answer: yes! sure! C++ is flexible, and almost everything is possible (especially such a simple things).

the detailed answer depends on your use cases.

  • how may other statics/globals depends on your signleton
  • when the very first access to your singleton going to happen (probably before main?)
  • lot of other things you have to take in account (most of them related to interaction of your singleton w/ other entities)
zaufi
  • 6,811
  • 26
  • 34