Derek
Derek

Reputation: 1135

Can everything in a singleton be static?

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.

Upvotes: 4

Views: 2960

Answers (5)

Vite Falcon
Vite Falcon

Reputation: 6641

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.

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145459

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?

Upvotes: 1

zaufi
zaufi

Reputation: 7129

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)

Upvotes: 0

Bejmax
Bejmax

Reputation: 945

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?

Upvotes: 1

goji
goji

Reputation: 7132

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.

Upvotes: 7

Related Questions