Small question about singletons created on the stack

Started by
19 comments, last by Gnollrunner 5 years, 8 months ago

One thing about those singleton. In the example you give the first one to be initialized is the memory manager., That imply that memory allocation is custom, and the singletons are object, not pointer to object, That mean that there is the possibility that the global destructor could destroy some memory after the memory manager is gone so crash.

It's a good idea to allocate the memory manager, init it. then allocate the singletons and init them,

And when shuting down, Deinit singletons, delete them, then deinit memory manager, and delete it. 

 

 

Advertisement
On 7/26/2018 at 7:01 AM, ChaosEngine said:

Those aren't singletons. They're globals, and they're actually stored on the heap.

Usually singletons have somekind of mechanism to prevent creating multiple instances from the same class, right ?

http://9tawan.net/en/

1 hour ago, mr_tawan said:

Usually singletons have somekind of mechanism to prevent creating multiple instances from the same class, right ?

I mean technically yes. You are supposed to have the constructor hidden and only have some  MySingleton::GetInstance() sort of call.  This tends to be OK if you are allocating stuff in global space  but sometimes you have to guarantee one singleton is constructed before another and then you typically have to initialize it when it is first requested, which means there has to be some sort of check in GetInstance to see if it's built yet.  This of course means there is overhead every time you request your singleton.

So the cheating way of doing it is just to construct stuff in the order it needs to be constructed on start up.  In this case it's a singleton in that there is only one of them, but it doesn't really follow the singleton pattern.  I personalty hate this kind of nit-picky stuff but there you have it.

2 minutes ago, Gnollrunner said:

In this case it's a singleton in that there is only one of them, but it doesn't really follow the singleton pattern.  I personalty hate this kind of nit-picky stuff but there you have it.

No, it's not a singleton, it's a single global instance. 

It might sound nitpicky, but there's a really important difference; there's nothing stopping you creating a second instance. 

The classic case for a singleton is something like an InputManager class. You'll only ever want one of those, right? Until you add split screen multiplayer.

The fundamental problem with singletons is that they enforce cardinality in the class, not the users of the class. The class shouldn't care if there is one object or 50 million.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
3 minutes ago, ChaosEngine said:

It might sound nitpicky, but there's a really important difference; there's nothing stopping you creating a second instance.

To me it's a really unimportant difference.  People argue about this stuff, but in reality creating a second instance of some big class that there is only supposed to be one instance off, is one of the easier bugs you are going to run in to.   I certainly wish that was the worst of my problems. 

18 minutes ago, Gnollrunner said:

To me it's a really unimportant difference.  People argue about this stuff, but in reality creating a second instance of some big class that there is only supposed to be one instance off, is one of the easier bugs you are going to run in to.   I certainly wish that was the worst of my problems. 

1

I think you're missing the point.

A singleton is a class that can only have one instance and the class itself enforces this. Anything else isn't a singleton.  

The idea behind it isn't to stop you creating a "second instance of some big class", it's supposed to manage something that there can be only one of (it was sometimes called the "Highlander" pattern :D ). Typical examples are print queues, network interfaces, etc. But in reality, it causes more problems than it solves. 

As you say, if someone creates a second instance of a class, that's actually not that big a problem (if the class is designed well in the first place). On the other hand, if someone designs a singleton on the assumption there'll never be another instance of that class, it leads to all kinds of problems when you inevitably do need a second instance.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
1 hour ago, Gnollrunner said:

To me it's a really unimportant difference.  People argue about this stuff, but in reality creating a second instance of some big class that there is only supposed to be one instance off, is one of the easier bugs you are going to run in to.   I certainly wish that was the worst of my problems. 

Well if the code is used only by the trusted group of people, then the pattern might not be really important. You can just scold someone when they do something wrong.

If the code is used by multiple team, then it's quite important to prevent bad uses of the code (eg. a class). It can be difficult to spot a problem later when codes already went to the production. 

http://9tawan.net/en/

2 hours ago, ChaosEngine said:

The idea behind it isn't to stop you creating a "second instance of some big class", it's supposed to manage something that there can be only one of (it was sometimes called the "Highlander" pattern :D ). Typical examples are print queues, network interfaces, etc. But in reality, it causes more problems than it solves.  

I know what it's for. I just think often, it isn't very useful. If someone creates a second print queue, you will most likely find that problem pretty quickly. I'm dubious how may serious problems singletons have prevented, and I have seen a few cases where they have contributed to problems, mainly when one singleton is dependent on another and the order of initialization is undefined because they are implemented as globals as they often are. This is probably more serious in C++ than say Java.......  So then programmers try to fix this by putting them on the heap and having the GetInstance function create them on the first call. This works except you now have an "if" for every call of GetInstance. Maybe some people don't care, but I try to avoid code that slows things down.

8 hours ago, Gnollrunner said:

I just think often, it isn't very useful.

I think we're actually in agreement on this. Singleton is an anti-pattern, and should be avoided. 

Not only does it not solve problems, it encourages bad design and reduces testability.

If you only need one thing at the moment, just create one thing. 

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
5 hours ago, ChaosEngine said:

I think we're actually in agreement on this. Singleton is an anti-pattern, and should be avoided.

In any case, getting back to the original code, the way it's written (however you want to call it) looks OK.  The reason is, the definitions are all in one translation unit (i.e. source file). Therefore they will be initialized in the order they are defined, and so the programmer has control over the order. Similarly the programmer has control over post creation initialization order, so everything is explicitly spelled out and there is no ambiguity.  This is the main issue I've run into with classic singletons since they are organized into separate translation units so the order of creation becomes undefined.

This topic is closed to new replies.

Advertisement