Reputation: 1135
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
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
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
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.
Upvotes: 0
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
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