Take the below code. If I were to add some private member data into this class, say a std::vector, would I make it static or not?
#include <string>
class Logger{
public:
static Logger* Instance();
bool openLogFile(std::string logFile);
void writeToLogFile();
bool closeLogFile();
private:
Logger(){}; // Private so that it can not be called
Logger(Logger const&){}; // copy constructor is private
Logger& operator=(Logger const&){}; // assignment operator is private
static Logger* m_pInstance;
};
**Code example shamelessly taken from here
Idiomatically, no. Other than that, there's nothing that keeps you from doing it.
Keep in mind though that if it is static, it needs to be defined and the member gets initialized before entry to main, when the program starts.
If it isn't static, it will get initialized when m_pInstance gets created (which can be useful if you need some lazy initialization).
The big problem is order of initialization. In C++, the singleton idiom
is usually used to resolve order of initialization issues, so that's
likely to be a problem: if the members are static, you can't be sure
that they have been constructed before you try to use them.
Related
In a class I have a static member that represents the singleton instance of that class:
class A {
public:
static const std::shared_ptr<A> INSTANCE;
private:
A();
};
In order to prevent more instances I made the constructor private. Now I have trouble to initialize the static var, because the initializer cannot access a private member. Here's the code I use in the .cpp file:
const std::shared_ptr<A> A::INSTANCE = std::make_shared<A>();
A factory method wouldn't help either, as it would have to be public as well. What else can I do to make this work? Note: I'd like to avoid the typical static get() method if possible.
You can't use make_shared, but you can just create the instance directly:
const std::shared_ptr<A> A::INSTANCE { new A };
The initialization of a static member is unrelated to the constructor, so the global statement is indeed the right way to go. Is it not working for you?
EDIT: I just realized you're trying to avoid using a singleton access method for some reason. Sounds suspiciously like the Borg pattern. :) Unrelated to you r specific question but I'd advise you to reconsider.
I will demonstrate my question using a Singleton pattern but it is a broader question. Please spare me the "Singletons are evil" lectures.
Version 1 of Singleton
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance; // This becomes a class member in Ver.2
return instance;
}
private:
// Constructor, forbid copy and assign operations etc...
}
Version 2 of Singleton
class Singleton
{
public:
static Singleton& getInstance()
{
return instance;
}
private:
static Singleton instance; // I'm here now!
// Constructor, forbid copy and assign operations etc...
}
I will now explain what I think will be the difference is between the two:
Version 1 instance will only be initialized once the flow of the program reaches the actual definition of instance (i.e some part of the program requests an instance using Singleton::getInstace()). Lazy instantiated in other words.
It will only be destroyed when the program terminates.
Version 2 instance will be initialized at the start of the program, before main() is called. Will also be destroyed only when the program terminates.
First of all, am I correct in the above assumptions?
Second, Is this behavior of initialization universal (say for global variables and functions)?
Last, Are there any other nuances I should be alerted about concerning this?
Thanks!
You are correct.
You should also notice that the 2nd version does not guarantee when will the object be created, only that it will be before the main function is called.
This will cause problems if that singleton depends on other singletons and etc
That is, the first version will give you greater control over your code, initialization order and of course - less bugs :)
I've got simple singleton class:
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
// private constructor, etc...
}
The question is how should I access class instance from its member functions?
I've seen various code snippets and now I'm curious whether they have any significant differences.
1.
void Singleton::something(){
Singleton &self = getInstance();
self.doSomething();
}
2.
void Singleton::something(){
this->doSomething();
}
3.
void Singleton::something(){
doSomething();
}
is unnecessary complication - in a non-static member function like something we already have an instance, so there is no need to get it separately.
and 3. are the same, only 3. is shorter and more idiomatic - using this-> to access a member in C++ is not common.
I don't think there should be any other member function to get class instance except Singleton::getInstance();, because this is why it exist. Do it as below:
Sungleton &dst=Singleton::getInstance();
In fact, no way to get instance from non-static member function. When there is no class instance , how can you call its non-static member.
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.
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.
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?
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?
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.
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)
I have a question with singlton.
Where should I declare the static member of the singleton class?
why not working like this
class singleton{
private:
static singleton & m_singleton;
public:
static singleton& get_instance{
return m_singleton;
}
}
but I have to be like this
class singleton{
public:
static singleton& get_instance{
static singleton & m_singleton;
return m_singleton;
}
}
What's the differnece?
I know there is another way to use pointer, but now I am only talking about the case to use an object.
Also another questions, what's the pros/cons to use pointer and reference for singleton ?
Thanks so much!
In the first case, the singleton is constructed (constructor called) when the program initializes, before main() is called. In this case you will also need to define the static variable somewhere in your cpp file.
In the second case the singleton is constructed when the function is first called. Mind you that this implementation is not thread safe since static variable initialization in functions is not thread safe. If two threads call this function for what appears to be the first time, there is a small chance you'll end up with two singletons.
Also notice you have a bug in the second one. You cannot define a reference without an initalization. This
static SomeClass &var;
Does not compile. You need to remove the reference to create an actual instance of the class, not a reference, and then return a reference to it.
If in the second example you define the static variable as a pointer you can avoid the threading problem I mentioned by carefully initializing the pointer. Read more about it in this class article (that talks about Java but the core issue is the same)