struct Z {
Z(long long); // can initialize with an long long
Z(long) = delete; // but not anything less
};
I am not sure how will this help to delete a instance of the singleton class.
I am seeing that whenever the app is closed, direct is called to CC_SAFE_RELEASE to delete all the nodes and related memory. But not sure how does it happen for non-node classes like singleton class.
The ā= deleteā syntax tells the compiler to ignore a function/method, I was suggesting it as a way to block the copy constructor and assignment operator for your singletons (a good practice). It doesnāt have anything to do with destructors or deleting an instance. When and how to delete your singleton is a very good question though, so I will answer that in a later post (I donāt want to address 2 topics in this one post in order to avoid confusion).
The old way to block the copy constructor / assignment operator is like in your example, you make them private in the header file and provide no implementation in the CPP file, like this:
OLD C++ WAY
// In your header:
class MySingleton {
private:
MySingleton(const MySingleton& arg); // Copy constructor
MySingleton& operator=(const MySingleton& arg); // Assignment operator
}
In C++11 you can do this, and to be completely thorough here are all of the methods to block:
I suppose this is nitpicking but I prefer the new C++ way, because my intention is clear that I want the copy constructor and assignment operators blocked.
I know you directed these questions to @slackmoehrle, so hopefully he doesnāt mind if I provide my opinion on them.
You need a destructor if your singleton allocates class members with new and needs to delete them, or it keeps file handles or network connections open and needs to close them, or it calls retain on CC2D objects and needs to release them, etc ā¦
Really though, only you can figure out if your singleton needs a destructor, because only the person who wrote the code knows if they have a resource that needs to be released at the end of the singletonās life.
As far as when to call the destructor for your singletons, I specifically do not allocate my singletons on the heap (using new) for this reason. My C++ code almost never calls delete explicitly. I declare variables at the automatic scope (local variable, class member, etc ā¦) wherever I can, and if I must instantiate something with new, the first thing I do is manage it with a smart pointer (and the smart pointer will be declared at the automatic scope).
Donāt manage things when you donāt have to, youāll just give yourself a headache chasing down bugs when you get something wrong.
If you see my singleton pattern in one of my earlier posts above, I define the singleton as a static local variable. C++ will call that static local variableās destructor when the program exits (meaning my singleton will exist for the lifetime of the program, which is the behavior I want), there is no need for me to ever do so explicitly. Here is a good explanation on the lifetime of a C++ static variable:
This pattern adheres to good RAII practices, and understanding RAII is crucial to writing good C++ code. That is why I declare just about everything I can at the automatic scope, and use smart pointers for everything I canāt. Here are some good resources for understand RAII:
@qwpeoriu
Thanks a lot for elaborate explanations.
I think Iāve cleared my doubts. Thanks
So, I also switched to completely C++11 style as what you suggested, works fine.
In case, I had to use new for the instance of singleton then at what point of program shall I be calling destructor (delete instance) if singleton remains for the entire life of the program(game). Or what happens in case the user force quits the programā¦ In that case, does OS handles the things automatically?
Just wanted to know if your other class members(variables) are all static because youāre not allocating memory to your singleton instance or it need not to be?
(Iām accessing non-static class members right nowā¦ working fine though.)
implement singleton, for example GameManager
GameManager.h
#include "singleton.h"
class GameManager : public Singleton<GameManager>
{
public:
GameManager();
// Game Play
int getGameScore();
void setGameScore(int latestScore);
private:
int gameScore;
};
Thanks a lot of detailed reply. Your solution is good.
I was reading somewhere that singletons objects (non static) created might not be thread safe. So, if weāre sure about how we are handling our objects, weāre fine to use it. Since, Iām not too techy in C++, itās ok for me to use this for simple games but may not be if the complexity of my future game is more and I might be unaware when it happens.
(Finally been answered by someone which I initially have been asking :D)
As always, thanks for a good explanation and code.
I know this comment might not be for me but initially I was using global variables through a namespace but I had to switch to singleton because I had around 100 variables which I didnāt want to allocate memory to when itās not needed.
Or donāt worry about the memory allocated since I doubt the size of the global state is all that large compared to the gameās Texture resources. Or store large states in global pointers (or unique/shared_ptr) and allocate as necessary.
Anyway, this thread is on correct singletons.
I use the cocos2d method just because thereās no thought involved and I came from c2d-ObjC.
I often use a static class with static members to load/save prefs as a cache for UserDefault.
Iāll consider qwperoiuās version going forward, but agree itās generally smart to avoid global state.
Could also serialize in/out any info that needs to exist across a scene transition, or pass the World state to each new scene (directly or using Dep.Inject.). Or store it in a temporary/permanently global using your gameās cocos2d::App instance.
p.s. I tend toward facetious remarks and partial-sarcasm when i want to play devilās advocate, but donāt want to write a real response of substance.